# CRM · Activity

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /crm/customer-activity/{email}/timeline

**Get a customer activity timeline**

`operationId: CustomerActivityController_getTimeline`

Everything a customer has done, in order — the behavioural history behind their record.

#### Signature

```http
GET /crm/customer-activity/{email}/timeline (email: string, types?: string, from?: string, to?: string, limit?: string, page?: string) -> The activity timeline
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/customer-activity/{email}/summary`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | Customer email. |
| `types` | query | string | — | Comma-separated activity types. |
| `from` | query | string | — | ISO date — start of the range. |
| `to` | query | string | — | ISO date — end of the range. |
| `limit` | query | string | — | Maximum rows. |
| `page` | query | string | — | Page number (1-based). |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The activity timeline |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/customer-activity/visitor/{visitorId}/timeline

**Get an anonymous visitor timeline**

`operationId: CustomerActivityController_getVisitorTimeline`

Activity for a visitor who has not identified themselves yet, tracked by visitor id. Calling `identify` links this history to a real customer.

#### Signature

```http
GET /crm/customer-activity/visitor/{visitorId}/timeline (visitorId: string, limit?: string, page?: string) -> The visitor timeline
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/customer-activity/identify`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `visitorId` | path | string | yes | Anonymous visitor id. |
| `limit` | query | string | — | Maximum rows. |
| `page` | query | string | — | Page number (1-based). |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The visitor timeline |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /crm/customer-activity/{email}/summary

**Get a customer activity summary**

`operationId: CustomerActivityController_getSummary`

Aggregate view of a customer's behaviour rather than the raw event list — visit counts, recency and engagement.

#### Signature

```http
GET /crm/customer-activity/{email}/summary (email: string) -> The activity summary
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/customer-activity/{email}/timeline`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | Customer email. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The activity summary |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/customer-activity/identify

**Identify a visitor**

`operationId: CustomerActivityController_identifyVisitor`

Links an anonymous visitor's history to a known customer — what happens at sign-up or sign-in, so the browsing that led to the account is not lost.

Call it as soon as identity is known; activity recorded before it stays attached to the visitor id.

#### Signature

```http
POST /crm/customer-activity/identify (body) -> The identification result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/customer-activity/record`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The visitor and who they turned out to be.

```json
{
  "visitorId": "vis_9k2m4h1p7q",
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The identification result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/customer-activity/record

**Record customer activity**

`operationId: CustomerActivityController_recordEvent`

Records an activity event against a customer or visitor — a page view, a search, a product view. The write behind the timeline.

#### Signature

```http
POST /crm/customer-activity/record (body) -> The recorded event
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- High-volume by nature — batch where you can rather than calling per interaction.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /crm/customer-activity/erase`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The event to record.

```json
{
  "visitorId": "vis_9k2m4h1p7q",
  "type": "product_view",
  "data": {
    "sku": "DRK-COLA-330"
  }
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The recorded event |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /crm/customer-activity/erase

**Erase customer activity**

`operationId: CustomerActivityController_eraseCustomer`

Deletes a customer's recorded activity — the data-subject erasure path for a deletion request.

Irreversible by design: the point is that the history genuinely goes.

#### Signature

```http
POST /crm/customer-activity/erase (body) -> The erasure result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Irreversible. This erases activity only — the customer record itself is deleted through the user API.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /crm/customer-activity/{email}/timeline`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Whose activity to erase.

```json
{
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The erasure result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

