Skip to content

Customers

A Customer is a reusable entity that groups a payer’s saved payment methods, payment history, and payment plans under a single identifier. Attaching customers to payment intents lets you:

  • Charge saved payment methods without the customer present
  • Link transactions to a payer for reporting and reconciliation
  • Set up recurring payment plans via the API

All customer operations require a secret key (sk_xxx).

Your customer reference is a candidate key

Section titled “Your customer reference is a candidate key”

Every customer has two identifiers. id (cus_…) is ours, minted when the customer is created. reference is yours — the identifier your own system already uses for that customer (a CRM id, a member number, a subscriber id) — and it is treated as a candidate key:

  • Unique per account. Two live customers on the same account cannot share a reference. Matching ignores surrounding whitespace and letter case (CRM-983 and crm-983 are the same reference), so a duplicate is refused at create, update and import time.
  • Optional, but the join key for everything that moves in bulk. When you import customers with an agent, set reference to your source system’s customer id; when you import their payment plans, each plan names its customer by customer_reference — no round-trip to look up cus_… ids for customers you created a minute ago, and it works just the same for customers created years ago through this API.
  • Stable. We never change it; only you can.

Set it at creation whenever you have one. A customer with no reference can only ever be named by its cus_… id.

Create with your own key
{ "name": "Alice Smith", "email": "alice@example.com", "reference": "alice-user-42" }

To find a customer by reference, pass it as the reference filter when you list customers. It is an exact match under the same rule as uniqueness, ignoring surrounding whitespace and letter case, so it returns at most one customer:

Look up by your own key
curl "https://api.elasticpay.co/api/v1/customers?reference=alice-user-42" \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

An empty data array means no customer on the account holds that reference. Agents connected over MCP get the same lookup from list_customers.

Terminal window
curl -X POST https://api.elasticpay.co/api/v1/customers \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Alice Smith",
"email": "alice@example.com",
"reference": "alice-user-42"
}'

Response

{
"id": "cus_0abc123def456ghi789jkl012mno",
"name": "Alice Smith",
"email": "alice@example.com",
"reference": "alice-user-42",
"created_at": "2026-04-01T10:00:00Z",
"updated_at": "2026-04-01T10:00:00Z"
}

The id (e.g. cus_0abc...) is the customer’s stable identifier to use in subsequent requests.

The reference field is your own identifier for the customer — a candidate key, unique per account, that you can look the customer up by and that bulk imports join on.

In sandbox, you can also pass test_clock: "clk_..." to attach the customer to a test clock at creation. The field is immutable, and clock-bound customers are excluded from the default customer list.

Terminal window
curl https://api.elasticpay.co/api/v1/customers/cus_0abc123def456ghi789jkl012mno \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Terminal window
curl "https://api.elasticpay.co/api/v1/customers?limit=20" \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response shape

{
"data": [],
"has_more": false
}

Supported query parameters:

Parameter Description
limit Number of results per page (default 20, max 100)
starting_after Cursor: return results after this customer ID
email Customers whose email or billing_email equals this address. Exact match, ignoring surrounding whitespace and letter case; several customers can share an address
reference Your own customer reference. Exact match, ignoring surrounding whitespace and letter case
test_clock Sandbox only: list customers attached to this test clock. Without it, clock-bound customers are excluded

Use PUT to update any mutable field. Fields not included in the request body are left unchanged.

Terminal window
curl -X PUT https://api.elasticpay.co/api/v1/customers/cus_0abc123def456ghi789jkl012mno \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email": "new-email@example.com"}'

Deleting a customer performs a soft-delete — the record is hidden from API responses and the portal but retained in the database for audit purposes. Payment intents and transactions associated with the customer are preserved.

Terminal window
curl -X DELETE https://api.elasticpay.co/api/v1/customers/cus_0abc123def456ghi789jkl012mno \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

A successful deletion returns 204 No Content.

Retrieve all saved payment methods (pm_xxx) for a customer:

Terminal window
curl https://api.elasticpay.co/api/v1/customers/cus_0abc123def456ghi789jkl012mno/payment_methods \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Pass customer_id when creating a payment intent to associate it with a customer:

Terminal window
curl -X POST https://api.elasticpay.co/api/v1/payment_intents \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 4900,
"currency": "AUD",
"customer_id": "cus_0abc123def456ghi789jkl012mno"
}'
Operation Required scope
Create / update / delete customers:write
Fetch / list customers:read

Secret keys (sk_xxx) have both scopes by default.