/api/v1/customers
A customer is the person (and the email addresses) that PayGate bills and writes to for a subscription. You create customers yourself, per app, before starting a subscription checkout (03.01); reminder emails (03.08) go to the customer’s addresses in the customer’s language.
| Endpoint | Auth |
|---|---|
POST /api/v1/customers | HMAC or Firebase ID Token |
GET /api/v1/customers/{id} | HMAC or Firebase ID Token |
PATCH /api/v1/customers/{id} | HMAC or Firebase ID Token |
Customers are private to your app. A customer of another app looks exactly like a missing one (404 not_found). With Firebase ID Token, a customer is bound to the token’s sub: only that end user can read, update or use it (anyone else gets 404 not_found, or 400 customer_not_found when used in a checkout).
POST /api/v1/customers
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Max 191 characters |
email | string | Yes | Valid email address — the To of every reminder |
cc_emails | string[] | No | Up to 5 valid addresses, added as Cc |
bcc_emails | string[] | No | Up to 5 valid addresses, added as Bcc |
merchant_customer_id | string | No | Your own id for this customer (max 191 characters); echoed in webhooks as merchant_customer_id |
locale | string | No | en (default) or vi — the language of emails and the hosted renewal page |
curl -X POST https://payments.example.com/api/v1/customers \
-H "X-App-Key: pgk_xxx" -H "X-Timestamp: 1700000000" -H "X-Signature: <HMAC>" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com",
"cc_emails": ["billing@example.com"],
"merchant_customer_id": "crm-1001",
"locale": "en"
}'
Response 201 Created:
{
"success": true,
"data": {
"id": "cus_5d2e7b9a1c4f8036ab12de45",
"name": "Jane Doe",
"email": "jane@example.com",
"cc_emails": ["billing@example.com"],
"bcc_emails": [],
"merchant_customer_id": "crm-1001",
"locale": "en",
"created_at": "2026-10-03 08:00:00",
"updated_at": "2026-10-03 08:00:00"
}
}
Notes:
- No duplicate check. Neither
emailnormerchant_customer_idhas to be unique: every call creates a new customer. Store the returnedidand reuse it instead of creating a customer per checkout. - Within one customer, an address that repeats the primary
email, or appears in bothcc_emailsandbcc_emails, is dropped from the lists.
GET /api/v1/customers/{id}
Returns the same object as above. Unknown id, another app’s customer (or, with Firebase ID Token, another user’s) returns 404 not_found.
PATCH /api/v1/customers/{id}
Partial update. Send only the fields to change: name, email, cc_emails, bcc_emails, merchant_customer_id, locale (other fields are ignored). cc_emails and bcc_emails replace the whole list; merchant_customer_id: null clears it; locale cannot be null. An empty body, or one without any updatable field, returns 400 invalid_request.
curl -X PATCH https://payments.example.com/api/v1/customers/cus_5d2e7b9a1c4f8036ab12de45 \
-H "X-App-Key: pgk_xxx" -H "X-Timestamp: 1700000000" -H "X-Signature: <HMAC>" \
-H "Content-Type: application/json" \
-d '{ "locale": "vi", "bcc_emails": [] }'
The response is the updated customer.
Errors
| Code | HTTP | When |
|---|---|---|
invalid_request | 400 | Validation failed (name/email missing or invalid, more than 5 cc_emails/bcc_emails, bad locale, empty PATCH body); message names the field |
not_found | 404 | Customer doesn’t exist or isn’t yours |
Using an unknown customer elsewhere returns customer_not_found — see Errors.