Account
Every Account endpoint.
/api/tenants/{id}Get your account
Strictly scoped to your own tenant: a request for another tenant's id answers 403, never that tenant's data. The response is an explicit allow list (`TenantService.getTenant`): a new internal column is never exposed by adding it to the table, only by being named here deliberately.
Auth: apiKey
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| id | path | required |
Responses
200 : Default Response
| Field | Type | Required | Description |
|---|---|---|---|
| tenant.apiKeys | array | required | |
| tenant.apiKeys[].createdAt | string | required · nullable | |
| tenant.apiKeys[].expiresAt | string | required · nullable | |
| tenant.apiKeys[].id | string | required | |
| tenant.apiKeys[].lastUsedAt | string | required · nullable | |
| tenant.apiKeys[].name | string | required | |
| tenant.apiKeys[].permissions | array | required | |
| tenant.apiKeys[].permissions[] | string | optional | |
| tenant.createdAt | string | required · nullable | |
| tenant.id | string | required | |
| tenant.name | string | required | |
| tenant.plan | string | required | |
| tenant.subdomain | string | required | |
| tenant.suspendReason | string | required · nullable | |
| tenant.suspended | boolean | required | |
| tenant.suspendedAt | string | required · nullable | |
| tenant.updatedAt | string | required · nullable | |
| tenant.usage | array | required | |
| tenant.usage[].createdAt | string | required · nullable | |
| tenant.usage[].emailsBounced | number | required | |
| tenant.usage[].emailsClicked | number | required | |
| tenant.usage[].emailsOpened | number | required | |
| tenant.usage[].emailsSent | number | required | |
| tenant.usage[].id | string | required | |
| tenant.usage[].period | string | required · nullable | |
| tenant.usage[].tenantId | string | required | |
| tenant.usage[].updatedAt | string | required · nullable |
curl https://api.zsender.io/api/tenants/{id} \
-H "Authorization: Bearer $ZSENDER_API_KEY"/api/tenants/{id}Rename your account
Requires a key with `admin`. `name` is the only field you can change. A plan is not something a key can grant itself.
Auth: apiKey
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| id | path | required |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | optional |
{
"name": "Northwind Trading"
}Responses
200 : Default Response
| Field | Type | Required | Description |
|---|---|---|---|
| tenant.apiKeys | array | required | |
| tenant.apiKeys[].createdAt | string | required · nullable | |
| tenant.apiKeys[].expiresAt | string | required · nullable | |
| tenant.apiKeys[].id | string | required | |
| tenant.apiKeys[].lastUsedAt | string | required · nullable | |
| tenant.apiKeys[].name | string | required | |
| tenant.apiKeys[].permissions | array | required | |
| tenant.apiKeys[].permissions[] | string | optional | |
| tenant.createdAt | string | required · nullable | |
| tenant.id | string | required | |
| tenant.name | string | required | |
| tenant.plan | string | required | |
| tenant.subdomain | string | required | |
| tenant.suspendReason | string | required · nullable | |
| tenant.suspended | boolean | required | |
| tenant.suspendedAt | string | required · nullable | |
| tenant.updatedAt | string | required · nullable | |
| tenant.usage | array | required | |
| tenant.usage[].createdAt | string | required · nullable | |
| tenant.usage[].emailsBounced | number | required | |
| tenant.usage[].emailsClicked | number | required | |
| tenant.usage[].emailsOpened | number | required | |
| tenant.usage[].emailsSent | number | required | |
| tenant.usage[].id | string | required | |
| tenant.usage[].period | string | required · nullable | |
| tenant.usage[].tenantId | string | required | |
| tenant.usage[].updatedAt | string | required · nullable |
curl https://api.zsender.io/api/tenants/{id} \
-X PUT \
-H "Authorization: Bearer $ZSENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Northwind Trading"
}'/api/tenants/{tenantId}/api-keysList your API keys
Metadata only: name, permissions, prefix, creation and last-used timestamps. Never the key value itself; see "Create an API key" for the one place that appears.
Auth: apiKey
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| tenantId | path | required |
Responses
200 : Default Response
| Field | Type | Required | Description |
|---|---|---|---|
| apiKeys | array | required | |
| apiKeys[].createdAt | string | required · nullable | |
| apiKeys[].expiresAt | string | required · nullable | |
| apiKeys[].id | string | required | |
| apiKeys[].keyPrefix | string | required | |
| apiKeys[].lastUsedAt | string | required · nullable | |
| apiKeys[].mode | string | required | |
| apiKeys[].name | string | required | |
| apiKeys[].permissions | array | required | |
| apiKeys[].permissions[] | string | optional | |
| apiKeys[].tenantId | string | required |
curl https://api.zsender.io/api/tenants/{tenantId}/api-keys \
-H "Authorization: Bearer $ZSENDER_API_KEY"/api/tenants/{tenantId}/api-keysCreate an API key
Requires a key with `admin`. The plaintext `key` is returned ONCE, in this response, and is never retrievable again; it is stored hashed. A key with `admin` can mint further keys, so treat it as the root credential for the account.
Auth: apiKey
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| tenantId | path | required |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| expiresAt | string | optional | |
| name | string | required | |
| permissions | array | required | |
| permissions[] | string | optional |
{
"expiresAt": "2027-01-01T00:00:00.000Z",
"name": "production-backend",
"permissions": [
"send",
"read"
]
}Responses
201 : Default Response
| Field | Type | Required | Description |
|---|---|---|---|
| apiKey.createdAt | string | required · nullable | |
| apiKey.expiresAt | string | required · nullable | |
| apiKey.id | string | required | |
| apiKey.key | string | required | |
| apiKey.message | string | required | |
| apiKey.name | string | required | |
| apiKey.permissions | array | required | |
| apiKey.permissions[] | string | optional |
curl https://api.zsender.io/api/tenants/{tenantId}/api-keys \
-X POST \
-H "Authorization: Bearer $ZSENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"expiresAt": "2027-01-01T00:00:00.000Z",
"name": "production-backend",
"permissions": [
"send",
"read"
]
}'/api/tenants/{tenantId}/api-keys/{keyId}Revoke an API key
Requires a key with `admin`. Effective immediately on the next request.
Auth: apiKey
Parameters
| Name | In | Required | Description |
|---|---|---|---|
| tenantId | path | required | |
| keyId | path | required |
Responses
204 : Default Response
curl https://api.zsender.io/api/tenants/{tenantId}/api-keys/{keyId} \
-X DELETE \
-H "Authorization: Bearer $ZSENDER_API_KEY"/v1/usage/currentCurrent month's usage and quota
The current calendar month's send counter against `Tenant.plan`'s quota. `plan` is the only input to both the monthly quota and the per-minute rate limit.
Auth: apiKey or jwt
Responses
200 : Default Response
| Field | Type | Required | Description |
|---|---|---|---|
| emails_bounced | number | required | |
| emails_clicked | number | required | |
| emails_opened | number | required | |
| percentage | number | required | |
| period | string | required | |
| quota | number | required | |
| remaining | number | required | |
| used | number | required |
curl https://api.zsender.io/v1/usage/current \
-H "Authorization: Bearer $ZSENDER_API_KEY"