Create, read, update, and delete customer records.

Endpoints

Method Path Description
GET /api/v1/teams/{teamId}/customers List customers
POST /api/v1/teams/{teamId}/customers Create a customer
GET /api/v1/teams/{teamId}/customers/{customerId} Get a customer
PATCH /api/v1/teams/{teamId}/customers/{customerId} Update a customer
DELETE /api/v1/teams/{teamId}/customers/{customerId} Delete a customer

The single-resource endpoints (/customers/{customerId}) accept both prefixed IDs (cus_abc123) and UUIDs. List filters operate on the underlying UUID columns, so tag and search use literal values, not prefixed IDs.


List Customers

GET /api/v1/teams/{teamId}/customers

Query Parameters

Parameter Type Description
page integer Page number (default: 1)
pageSize integer Results per page (default: 20, max: 100)
status string Filter: active, inactive
sentiment string Filter: happy, neutral, frustrated, angry
search string Search by name or email
tag string Filter by tag (exact match)

Example

curl "https://www.cstar.help/api/v1/teams/{teamId}/customers?status=active&search=jane" \
  -H "Authorization: Bearer sk_live_xxx"

Response

{
  "success": true,
  "data": [
    {
      "id": "cus_x9Y8z7W6v5U4",
      "object": "customer",
      "name": "Jane Doe",
      "email": "jane@example.com",
      "sentiment": "happy",
      "status": "active",
      "tags": ["vip", "enterprise"],
      "notes": "Enterprise customer since 2024",
      "customFields": {
        "company": "Acme Corp",
        "plan": "enterprise"
      },
      "ticketCount": 5,
      "metadata": {},
      "createdAt": "2025-01-15T10:00:00Z",
      "updatedAt": "2026-03-30T10:30:00Z"
    }
  ],
  "pagination": {
    "total": 156,
    "page": 1,
    "pageSize": 20,
    "hasMore": true
  }
}

Create Customer

POST /api/v1/teams/{teamId}/customers

Requires a secret key.

Field Type Required Description
name string Yes Display name
email string Yes Email address (must be unique per team)
sentiment string No happy, neutral (default), frustrated, angry
status string No active (default), inactive
tags string[] No Array of tags
notes string No Internal notes
customFields object No Key-value pairs for custom data
metadata object No Developer metadata (max 50 keys, string values)
curl -X POST "https://www.cstar.help/api/v1/teams/{teamId}/customers" \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-john-smith-001" \
  -d '{
    "name": "John Smith",
    "email": "john@example.com",
    "tags": ["trial"]
  }'

Returns 201 Created. If the email already exists on the team, returns 409 Conflict.


Get Customer

GET /api/v1/teams/{teamId}/customers/{customerId}

Returns the customer object plus a recentTickets array of their 10 most recent tickets.

Response

{
  "success": true,
  "data": {
    "id": "cus_x9Y8z7W6v5U4",
    "object": "customer",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "sentiment": "happy",
    "status": "active",
    "tags": ["vip"],
    "ticketCount": 5,
    "recentTickets": [
      {
        "id": "tkt_abc123",
        "title": "Login issue",
        "status": "resolved",
        "createdAt": "2026-03-29T14:00:00Z"
      }
    ],
    "createdAt": "2025-01-15T10:00:00Z",
    "updatedAt": "2026-03-30T10:30:00Z"
  }
}

The field name is recentTickets (camelCase). Earlier docs showed it as tickets, that was wrong.

To skip the embedded tickets, pass any non-tickets value to expand, for example ?expand=customer. Without an expand query parameter, recent tickets are included by default.


Update Customer

PATCH /api/v1/teams/{teamId}/customers/{customerId}

Requires a secret key. Send only the fields you want to change.

Field Type Description
name string Update display name
email string Update email (checked for uniqueness)
sentiment string happy, neutral, frustrated, angry
status string active, inactive
tags string[] Replace the tags array
notes string Update internal notes
customFields object Replace custom fields
metadata object Merged with existing metadata (set a key to null to remove it)

Changing the email to one that already belongs to another customer on the team returns 409 Conflict.


Delete Customer

DELETE /api/v1/teams/{teamId}/customers/{customerId}

Requires a secret key with delete permissions.

Returns:

{
  "success": true,
  "data": { "deleted": true, "id": "cus_x9Y8z7W6v5U4" }
}

Metadata

The metadata field follows Stripe conventions:

  • Max 50 keys per resource
  • Keys: max 40 characters, strings only
  • Values: max 500 characters, strings only
  • Set a key to null to remove it
  • PATCH merges with existing metadata (doesn't replace the whole object)

Webhook Events

Event Fires When
customer.created Customer is created
customer.updated Customer fields change
customer.deleted Customer is deleted

Related