Your AI Connector Docs

Errors & Pagination

This page covers two things every integration needs to handle: what a failed request looks like, and how to page through endpoints that return lists.


The error envelope

When a request fails, the response is always JSON with the same shape — a success flag set to false, a human-readable error message, and a numeric error_code that matches the HTTP status:

{
  "success": false,
  "error": "Invalid cursor",
  "error_code": 400
}

Because success and error_code are always present, you can branch on them without inspecting raw HTTP status codes if you prefer. A successful response always has success: true.


Status codes

Status error_code Meaning What to do
200 Success Read the response data.
201 Resource created Save the returned ID (e.g. campaign_id, contactId).
400 400 Bad request A parameter is missing or invalid. Read the error message and fix the request.
401 401 Unauthorized Your API key is missing or invalid. Check the key and how you are sending it — see Authentication.
403 403 Forbidden Your plan does not include API access. See API Access or contact hi@youraiconnector.com.
404 404 Not found The resource (e.g. a contact, campaign, or task ID) does not exist on your account.
409 409 Conflict The resource already exists — for example, creating a contact whose phone number is already on your account.
429 429 Rate limited You have exceeded 300 requests per minute (or the wider 1,200/minute account ceiling). Back off and retry shortly.
500 500 Server error Something went wrong on our side. Retry after a short wait; email hi@youraiconnector.com if it persists.

A few examples of what these look like in practice:

{
  "success": false,
  "error_code": 401,
  "error": "Invalid API key"
}
{
  "success": false,
  "error": "A contact with this phone number already exists",
  "error_code": 409
}
{
  "success": false,
  "error_code": 429,
  "error": "Rate limit exceeded. Please try again later."
}

Handling errors well

  • Check success (or the status code) before reading data. Do not assume a response body has the field you expect.
  • Retry 429 and 500 with a short back-off — wait, then try again. Do not retry 400, 401, 403, 404, or 409; those will keep failing until you change the request.
  • Read the error message. It usually tells you exactly which field is wrong.

Pagination

List endpoints (such as GET /contacts, GET /campaigns, and GET /tasks) return results in pages so a single call never has to load your whole account. Pagination uses an opaque cursor.

Two query parameters control it:

Parameter Description
limit How many items to return per page. Defaults vary by endpoint (often 50); the maximum is 100.
cursor An opaque pointer to the next page. Leave it off for the first page.

Each page includes a next_cursor field in the response:

  • If next_cursor is a string, there are more results — pass it as the cursor on your next request.
  • If next_cursor is null, you have reached the last page. Stop.

A single page of contacts looks like this:

{
  "success": true,
  "contacts": [
    { "id": "abc123", "first_name": "Jane", "phone_number": "+15551234567" },
    { "id": "def456", "first_name": "John", "phone_number": "+15557654321" }
  ],
  "next_cursor": "eyJsYXN0IjoiZGVmNDU2In0"
}

Note: A cursor is opaque — do not try to parse, build, or modify it. Only ever pass back a next_cursor value you received from a previous response.


Paging through all contacts

To collect an entire list, start with no cursor and keep calling until next_cursor comes back null.

cURL

This example walks the first two pages by hand. Run the first call, copy the next_cursor from its response into CURSOR, then run the second call. Repeat until next_cursor is null.

# First page
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100"

# Next page — paste the next_cursor from the previous response
CURSOR="eyJsYXN0IjoiZGVmNDU2In0"
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100&cursor=$CURSOR"

JavaScript

async function getAllContacts() {
  const all = [];
  let cursor = null;

  do {
    const url = new URL("https://api.youraiconnector.com/v1/contacts");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);

    const res = await fetch(url, {
      headers: { "X-API-Key": "YOUR_API_KEY" },
    });
    const data = await res.json();

    if (!data.success) throw new Error(data.error);

    all.push(...data.contacts);
    cursor = data.next_cursor;
  } while (cursor);

  return all;
}

Python

import requests

def get_all_contacts():
    all_contacts = []
    cursor = None

    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor

        res = requests.get(
            "https://api.youraiconnector.com/v1/contacts",
            params=params,
            headers={"X-API-Key": "YOUR_API_KEY"},
        )
        data = res.json()

        if not data["success"]:
            raise Exception(data["error"])

        all_contacts.extend(data["contacts"])
        cursor = data["next_cursor"]

        if not cursor:
            break

    return all_contacts

The same loop works for any paginated endpoint — just change the path and the field you read from the response (campaigns, tasks, and so on).


Next steps

  • Authentication — the four ways to send your key.
  • Contacts — the full contact endpoints used in the examples above.
  • API Keys — check your live rate-limit usage to avoid 429s.