On this page
- Endpoints
- List customers
- Query parameters
- Request
- Response 200
- Create a customer
- Request body
- Request
- Response 201
- Get a customer
- Query parameters
- Request
- Response 200
- Update a customer
- Request body
- Request
- Response 200
- Delete a customer
- Request
- Response 204
- List addresses
- Query parameters
- Request
- Response 200
- Create an address
- Request body
- Request
- Response 201
- Update an address
- Request body
- Request
- Response 200
- Delete an address
- Request
- Response 204
- List notes
- Request
- Response 200
- Create a note
- Request body
- Request
- Response 201
- Delete a note
- Request
- Response 204
- Webhooks
- The customer object
- The address object
- The customer note object
Customers
Customers represent the people who buy from your store. Each customer has a unique email address, contact details, and computed order statistics. Customers can have multiple addresses for billing and shipping, and internal notes for your team.
Base URL: https://api.hydrajs.dev
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/v1/customers |
Secret | List customers |
POST |
/v1/customers |
Secret | Create a customer |
GET |
/v1/customers/{id} |
Secret | Get a customer |
PATCH |
/v1/customers/{id} |
Secret | Update a customer |
DELETE |
/v1/customers/{id} |
Secret | Delete a customer (soft) |
GET |
/v1/customers/{id}/addresses |
Secret | List addresses |
POST |
/v1/customers/{id}/addresses |
Secret | Create an address |
PATCH |
/v1/addresses/{id} |
Secret | Update an address |
DELETE |
/v1/addresses/{id} |
Secret | Delete an address |
GET |
/v1/customers/{id}/notes |
Secret | List notes |
POST |
/v1/customers/{id}/notes |
Secret | Create a note |
DELETE |
/v1/customers/{id}/notes/{note_id} |
Secret | Delete a note |
ℹSecret keys only
All customer, address, and note endpoints require a secret API key (sk_live_* or sk_test_*).
Publishable keys cannot access customer data.
List customers
GET /v1/customers
Returns a paginated list of customers. Supports search, filtering, and sorting. Computed fields order_count and total_spent are included for each customer.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 25 |
Results per page (1-100) |
cursor |
string | - | Pagination cursor from a previous response |
sort |
string | created_at |
Sort field: created_at, updated_at, name, relevance |
order |
string | desc |
Sort direction: asc, desc |
email |
string | - | Filter by exact email address |
search |
string | - | Full-text search across name and email (max 200 chars) |
status |
string | - | Filter by status: active, inactive |
created_after |
ISO 8601 | - | Filter: created after this date |
min_orders |
integer | - | Filter: minimum order count |
max_orders |
integer | - | Filter: maximum order count |
min_spent |
integer | - | Filter: minimum lifetime spend in cents |
group_id |
string | - | Filter: customers belonging to this customer group |
expand |
string | - | Comma-separated: metafields |
fields |
string | - | Comma-separated fields to return |
ℹSorting by relevance
The relevance sort is only meaningful when combined with a search query. Without a search
term, results fall back to created_at ordering.
Request
curl https://api.hydrajs.dev/v1/customers?search=smith&limit=10 \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": [
{
"id": "cus_abc123",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-555-0123",
"order_count": 12,
"total_spent": 89450,
"tags": ["vip", "wholesale"],
"metadata": {},
"active_price_key": null,
"company": "Acme Corp",
"status": "active",
"tax_number": null,
"tax_number_type": null,
"created_at": "2026-02-10T08:30:00Z",
"updated_at": "2026-08-15T16:00:00Z"
}
],
"pagination": {
"cursor": "eyJ0IjoiMjAyNi...",
"has_more": true,
"total": 156
}
}
Create a customer
POST /v1/customers
Creates a new customer. The email must be unique within the project. Returns the created customer with 201.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | Email address (max 255 chars) |
first_name |
string | Yes | First name (1-100 chars) |
last_name |
string | Yes | Last name (1-100 chars) |
phone |
string | No | Phone number (max 30 chars) |
company |
string | No | Company name (max 255 chars) |
status |
string | No | active (default) or inactive |
tags |
string[] | No | Array of tags (max 25 tags, each max 100 chars) |
metadata |
object | No | Arbitrary key-value pairs (max 50 keys) |
active_price_key |
string | No | Price list slug for customer-specific pricing (max 50 chars). Set null to clear |
locale |
string | No | Preferred language (BCP 47, max 10 chars, e.g. en, es-419). Determines email language. null = use project default |
tax_number |
string | No | Tax identification number (max 50 chars) |
tax_number_type |
string | No | Tax number type: vat, ein, gst, abn, nif, siren, siret, nzbn, gst_hst, qst, other |
Request
curl -X POST https://api.hydrajs.dev/v1/customers \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-555-0123",
"company": "Acme Corp",
"tags": ["vip"],
"metadata": { "referral_source": "instagram" }
}'
Response 201
{
"data": {
"id": "cus_def456",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-555-0123",
"order_count": 0,
"total_spent": 0,
"tags": ["vip"],
"metadata": { "referral_source": "instagram" },
"active_price_key": null,
"company": "Acme Corp",
"status": "active",
"tax_number": null,
"tax_number_type": null,
"created_at": "2026-08-17T09:00:00Z",
"updated_at": "2026-08-17T09:00:00Z"
}
}
⚠Unique email
If a customer with the same email already exists in this project, the request fails with a 409 Conflict error.
Get a customer
GET /v1/customers/{id}
Returns a single customer by ID. Use expand to include related resources inline.
Query parameters
| Parameter | Type | Description |
|---|---|---|
expand |
string | Comma-separated: addresses, metafields |
fields |
string | Comma-separated fields to return |
Request
curl https://api.hydrajs.dev/v1/customers/cus_abc123?expand=addresses \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": {
"id": "cus_abc123",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-555-0123",
"order_count": 12,
"total_spent": 89450,
"tags": ["vip", "wholesale"],
"metadata": {},
"active_price_key": null,
"company": "Acme Corp",
"status": "active",
"tax_number": null,
"tax_number_type": null,
"addresses": [
{
"id": "addr_abc123",
"customer_id": "cus_abc123",
"first_name": "Jane",
"last_name": "Smith",
"company": null,
"line1": "123 Main Street",
"line2": "Apt 4B",
"city": "San Francisco",
"state": "CA",
"postal_code": "94102",
"country": "US",
"phone": "+1-555-0123",
"is_default": true,
"created_at": "2026-02-10T08:35:00Z",
"updated_at": "2026-02-10T08:35:00Z"
}
],
"created_at": "2026-02-10T08:30:00Z",
"updated_at": "2026-08-15T16:00:00Z"
}
}
Update a customer
PATCH /v1/customers/{id}
Partially updates a customer. Send only the fields you want to change. Returns the updated customer.
Request body
All fields are optional:
| Field | Type | Description |
|---|---|---|
email |
string | Email address (max 255 chars). Must be unique |
first_name |
string | First name (1-100 chars) |
last_name |
string | Last name (1-100 chars) |
phone |
string | null | Phone number (max 30 chars). Set null to clear |
company |
string | null | Company name (max 255 chars). Set null to clear |
status |
string | active or inactive |
tags |
string[] | Array of tags (max 25 tags, each max 100 chars) |
metadata |
object | Arbitrary key-value pairs (max 50 keys) |
active_price_key |
string | null | Price list slug. Set null to clear |
locale |
string | null | Preferred language (BCP 47, max 10 chars). Set null to clear |
tax_number |
string | null | Tax identification number (max 50 chars). Set null to clear |
tax_number_type |
string | null | Tax number type. Set null to clear |
⚠Tags replace, not merge
Sending tags replaces the entire array. To add a tag, fetch the current tags, append, and send
the full list.
Request
curl -X PATCH https://api.hydrajs.dev/v1/customers/cus_abc123 \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+1-555-9999",
"company": "Acme Corp",
"tags": ["vip", "wholesale", "loyalty-gold"],
"metadata": { "referral_source": "instagram", "loyalty_tier": "gold" }
}'
Response 200
{
"data": {
"id": "cus_abc123",
"email": "jane.smith@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+1-555-9999",
"order_count": 12,
"total_spent": 89450,
"tags": ["vip", "wholesale", "loyalty-gold"],
"metadata": { "referral_source": "instagram", "loyalty_tier": "gold" },
"active_price_key": null,
"company": "Acme Corp",
"status": "active",
"tax_number": null,
"tax_number_type": null,
"created_at": "2026-02-10T08:30:00Z",
"updated_at": "2026-08-17T10:15:00Z"
}
}
Delete a customer
DELETE /v1/customers/{id}
Soft-deletes a customer. The customer is hidden from all queries and their email is freed for reuse. Permanently purged after 30 days.
Request
curl -X DELETE https://api.hydrajs.dev/v1/customers/cus_abc123 \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 204
Empty body.
List addresses
GET /v1/customers/{id}/addresses
Returns all addresses for a customer, ordered with the default address first.
Query parameters
| Parameter | Type | Description |
|---|---|---|
fields |
string | Comma-separated fields to return |
Request
curl https://api.hydrajs.dev/v1/customers/cus_abc123/addresses \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": [
{
"id": "addr_abc123",
"customer_id": "cus_abc123",
"first_name": "Jane",
"last_name": "Smith",
"company": null,
"line1": "123 Main Street",
"line2": "Apt 4B",
"city": "San Francisco",
"state": "CA",
"postal_code": "94102",
"country": "US",
"phone": "+1-555-0123",
"is_default": true,
"created_at": "2026-02-10T08:35:00Z",
"updated_at": "2026-02-10T08:35:00Z"
},
{
"id": "addr_def456",
"customer_id": "cus_abc123",
"first_name": "Jane",
"last_name": "Smith",
"company": null,
"line1": "456 Oak Avenue",
"line2": null,
"city": "Los Angeles",
"state": "CA",
"postal_code": "90001",
"country": "US",
"phone": null,
"is_default": false,
"created_at": "2026-06-20T14:00:00Z",
"updated_at": "2026-06-20T14:00:00Z"
}
]
}
Create an address
POST /v1/customers/{id}/addresses
Creates a new address for a customer.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
first_name |
string | No | First name (max 100 chars) |
last_name |
string | No | Last name (max 100 chars) |
company |
string | No | Company name (max 255 chars) |
line1 |
string | Yes | Street address line 1 (1-255 chars) |
line2 |
string | No | Street address line 2 (max 255 chars) |
city |
string | Yes | City (1-100 chars) |
state |
string | No | State or province (1-100 chars) |
postal_code |
string | No | Postal / ZIP code (1-20 chars) |
country |
string | Yes | ISO 3166-1 alpha-2 country code (2 letters, e.g. US) |
phone |
string | No | Phone number (max 30 chars) |
is_default |
boolean | No | Set as default address (default: false) |
ℹDefault address
Setting is_default: true automatically unsets the previous default address for this customer.
Only one address can be the default at a time.
Request
curl -X POST https://api.hydrajs.dev/v1/customers/cus_abc123/addresses \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Smith",
"line1": "789 Elm Street",
"city": "Portland",
"state": "OR",
"postal_code": "97201",
"country": "US",
"is_default": false
}'
Response 201
{
"data": {
"id": "addr_ghi789",
"customer_id": "cus_abc123",
"first_name": "Jane",
"last_name": "Smith",
"company": null,
"line1": "789 Elm Street",
"line2": null,
"city": "Portland",
"state": "OR",
"postal_code": "97201",
"country": "US",
"phone": null,
"is_default": false,
"created_at": "2026-08-17T11:00:00Z",
"updated_at": "2026-08-17T11:00:00Z"
}
}
Update an address
PATCH /v1/addresses/{id}
Partially updates an address. Send only the fields you want to change. Returns the updated address.
Request body
All fields are optional:
| Field | Type | Description |
|---|---|---|
first_name |
string | null | First name (max 100 chars). Set null to clear |
last_name |
string | null | Last name (max 100 chars). Set null to clear |
company |
string | null | Company name (max 255 chars). Set null to clear |
line1 |
string | Street address line 1 (1-255 chars) |
line2 |
string | null | Street address line 2 (max 255 chars). Set null to clear |
city |
string | City (1-100 chars) |
state |
string | null | State or province (1-100 chars). Set null to clear |
postal_code |
string | null | Postal / ZIP code (1-20 chars). Set null to clear |
country |
string | ISO 3166-1 alpha-2 country code (2 letters) |
phone |
string | null | Phone number (max 30 chars). Set null to clear |
is_default |
boolean | Set as default address |
Request
curl -X PATCH https://api.hydrajs.dev/v1/addresses/addr_abc123 \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"line1": "123 Main Street, Suite 200",
"phone": "+1-555-0456"
}'
Response 200
{
"data": {
"id": "addr_abc123",
"customer_id": "cus_abc123",
"first_name": "Jane",
"last_name": "Smith",
"company": null,
"line1": "123 Main Street, Suite 200",
"line2": "Apt 4B",
"city": "San Francisco",
"state": "CA",
"postal_code": "94102",
"country": "US",
"phone": "+1-555-0456",
"is_default": true,
"created_at": "2026-02-10T08:35:00Z",
"updated_at": "2026-08-17T11:30:00Z"
}
}
Delete an address
DELETE /v1/addresses/{id}
Permanently deletes an address.
Request
curl -X DELETE https://api.hydrajs.dev/v1/addresses/addr_def456 \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 204
Empty body.
List notes
GET /v1/customers/{id}/notes
Returns all internal notes for a customer, ordered newest first. Notes are visible only to your team via secret keys.
Request
curl https://api.hydrajs.dev/v1/customers/cus_abc123/notes \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 200
{
"data": [
{
"id": "cnote_abc123",
"customer_id": "cus_abc123",
"content": "Customer requested invoice copy.",
"author_type": "admin",
"author_id": "user_abc",
"created_at": "2026-08-20T10:00:00Z",
"updated_at": "2026-08-20T10:00:00Z"
}
]
}
Create a note
POST /v1/customers/{id}/notes
Adds an internal note to a customer. The author is recorded from the authenticated context.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
content |
string | Yes | Note text (1-5000 chars) |
Request
curl -X POST https://api.hydrajs.dev/v1/customers/cus_abc123/notes \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Customer requested invoice copy."
}'
Response 201
{
"data": {
"id": "cnote_def456",
"customer_id": "cus_abc123",
"content": "Customer requested invoice copy.",
"author_type": "admin",
"author_id": "user_abc",
"created_at": "2026-08-20T10:05:00Z",
"updated_at": "2026-08-20T10:05:00Z"
}
}
Delete a note
DELETE /v1/customers/{id}/notes/{note_id}
Permanently removes an internal note.
Request
curl -X DELETE https://api.hydrajs.dev/v1/customers/cus_abc123/notes/cnote_abc123 \
-H "Authorization: Bearer sk_live_YOUR_KEY"
Response 204
Empty body.
Webhooks
Customer changes fire the following webhook events:
| Event | Trigger |
|---|---|
customer.created |
Customer created |
customer.updated |
Customer fields updated |
The customer object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: cus_) |
email |
string | Email address |
first_name |
string | First name |
last_name |
string | Last name |
phone |
string | null | Phone number |
company |
string | null | Company name |
status |
string | active or inactive |
order_count |
integer | Total number of orders (computed) |
total_spent |
integer | Lifetime spend in cents (computed, paid orders only) |
tags |
string[] | Customer tags |
metadata |
object | Arbitrary key-value pairs |
active_price_key |
string | null | Price list slug for customer-specific pricing |
locale |
string | null | Preferred language (BCP 47, e.g. en, es-419). null = project default |
tax_number |
string | null | Tax identification number |
tax_number_type |
string | null | Tax number type (vat, ein, gst, etc.) |
addresses |
object[] | Expanded with ?expand=addresses |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |
The address object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: addr_) |
customer_id |
string | Parent customer ID |
first_name |
string | null | First name |
last_name |
string | null | Last name |
company |
string | null | Company name |
line1 |
string | Street address line 1 |
line2 |
string | null | Street address line 2 |
city |
string | City |
state |
string | null | State or province |
postal_code |
string | null | Postal / ZIP code |
country |
string | ISO 3166-1 alpha-2 country code |
phone |
string | null | Phone number |
is_default |
boolean | Whether this is the customer’s default address |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |
The customer note object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: cnote_) |
customer_id |
string | Parent customer ID |
content |
string | Note text |
author_type |
string | admin or api_key |
author_id |
string | null | ID of the author (user or API key) |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |