API Conventions

Before calling any specific endpoint, this page is worth reading once. The patterns documented here — how requests are structured, what responses look like, how errors are formatted, how pagination works — are consistent across the entire Ziett API. Understanding them once means you won't be surprised anywhere in the reference.


Base URL

All requests go to:

https://api.ziett.co/c/v1

Every path in this reference is relative to that base. So /messages means https://api.ziett.co/c/v1/messages.

Versioning

The current version is v1. When breaking changes are introduced, they will ship under a new version prefix (e.g., /c/v2) with advance notice and a deprecation window for the previous version.


Requests

HTTP Verbs

MethodUsage
GETRetrieve a resource or a list of resources. Never modifies state.
POSTCreate a new resource or trigger an operation.
PATCHPartially update an existing resource. Only the fields you send are modified.
DELETEPermanently remove a resource.

Content Type

All request bodies must be sent as JSON:

Content-Type: application/json

Timestamps and IDs

All timestamps in both requests and responses follow ISO 8601 in UTC:

2025-07-14T10:30:00.000000+00:00

All resource identifiers use the UUID format:

550e8400-e29b-41d4-a716-446655440000

Responses

Synchronous — 200 OK

Operations that complete immediately return 200 OK with the resource directly in the body.

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "to": "+2449XXXXXXXX",
  "body": "Your verification code is 482910.",
  "status": "delivered",
  "created_at": "2025-07-14T10:30:00.000000+00:00"
}

Asynchronous — 202 Accepted

Operations that involve external networks (carriers, Meta) are queued and processed in the background. The API returns 202 Accepted immediately with an identifier to track the operation.

{
  "message": "Campaign validation successful. Processing 1,500 messages in the background.",
  "campaign_id": "550e8400-e29b-41d4-a716-446655440000"
}

Store the returned identifier and use it to query status or match against incoming webhook events. Do not poll the API in a tight loop — design around event-driven callbacks.

Resource Creation — 201 Created

When a resource is created synchronously, the API returns 201 Created with the full representation of the newly created object.


Errors

Ziett uses standard HTTP status codes. Codes in the 4xx range indicate a problem with your request. Codes in the 5xx range indicate a problem on Ziett's side — these are rare, but if they persist, check the status page.

Error Object

Every error response — regardless of cause — returns the same JSON structure:

FieldTypeDescription
codestringMachine-readable error identifier (e.g., BILLING_INSUFFICIENT_FUNDS). Use this for programmatic error handling.
messagestringHuman-readable description of what went wrong.
statusintegerThe HTTP status code.
trace_idstringUnique identifier for this request. Always include this when contacting support.
timestampstringISO 8601 timestamp of when the error occurred.
servicestringThe internal Ziett service that generated the error (e.g., core, billing).
fieldsobject(Optional) Present only on validation errors. Maps field names to specific error messages.

Examples

{
  "code": "VALIDATION_ERROR",
  "message": "One or more fields failed validation.",
  "status": 422,
  "trace_id": "f812a3bc91e044358a9e7011c456d901",
  "timestamp": "2025-07-14T10:30:00.000000+00:00",
  "service": "core",
  "fields": {
    "to": "Must be a valid E.164 formatted phone number (e.g., +2449XXXXXXXX).",
    "body": "This field is required and cannot be empty."
  }
}

Common Error Codes

CodeStatusMeaning
AUTH_INVALID_API_KEY401API key is missing, malformed, or revoked.
AUTH_INVALID_SCOPE403API key does not have the required scope for this operation.
RESOURCE_NOT_FOUND404The resource does not exist or does not belong to your organization.
VALIDATION_ERROR422One or more request fields failed validation. Check the fields object.
BILLING_INSUFFICIENT_FUNDS402Account credit balance is below the cost of this operation.
RATE_LIMIT_EXCEEDED429Too many requests. Retry with exponential backoff.
INTERNAL_SERVER_ERROR500Unexpected error on Ziett's side. Retry after a short delay.

Pagination

All GET endpoints that return lists use a consistent pagination envelope.

Query Parameters

ParameterTypeDefaultMaxDescription
pageinteger1The page number to retrieve.
sizeinteger30200Number of records per page.
order_bystringcreated_atField to sort results by.
orderstringdescSort direction: asc or desc.

Response Envelope

{
  "total": 1250,
  "page": 2,
  "size": 50,
  "pages": 25,
  "entries": [
    { "id": "...", "to": "+2449XXXXXXXX", "status": "delivered" },
    { "id": "...", "to": "+2449XXXXXXXX", "status": "failed" }
  ]
}
FieldTypeDescription
totalintegerTotal number of matching records across all pages.
pageintegerThe current page number.
sizeintegerRecords per page as requested.
pagesintegerTotal pages available. Iterate until page >= pages.
entriesarrayThe records for the current page.

Iterating All Records

import httpx

headers = {"X-API-KEY": "zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
all_messages = []
page = 1

while True:
    response = httpx.get(
        "https://api.ziett.co/c/v1/messages",
        headers=headers,
        params={"page": page, "size": 200},
    )
    data = response.json()
    all_messages.extend(data["entries"])

    if page >= data["pages"]:
        break

    page += 1

print(f"Retrieved {len(all_messages)} messages.")

Idempotency

For POST requests, you can supply an Idempotency-Key header to safely retry without risk of duplicate processing.

POST /c/v1/messages HTTP/1.1
Idempotency-Key: my-unique-request-id-7f3a8bc
X-API-KEY: zk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

If a request with the same key is received within a 24-hour window, Ziett returns the original response without re-executing the operation. This is especially useful when a network timeout prevents you from knowing whether a previous request succeeded.

Use a UUID or a combination of your internal resource ID and a timestamp as the key value — something guaranteed to be unique per logical operation.


With these patterns in mind, head to Send Message to make your first API call.