> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bizzyco.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Learn the basics of the Bizzy API

The Bizzy API provides programmatic access to your business communication data,
including messages, contacts, customers, and businesses. Use it to build
integrations, automate workflows, and extend Bizzy's capabilities.

**Quick reference for AI agents:**

```json theme={null}
{
    "baseUrl": "https://api.bizzyco.ai/v1",
    "auth": "Authorization: Bearer <api-key>",
    "responseEnvelope": {
        "data": "T",
        "meta": { "pagination": { "limit": 10, "offset": 0, "hasMore": true } }
    },
    "errorEnvelope": {
        "error": {
            "message": "string",
            "code": "string",
            "details": "object|undefined"
        }
    },
    "pagination": ["limit (1-100)", "offset (>=0)", "sortOrder (asc|desc)"],
    "ids": "UUIDv4",
    "timestamps": "ISO 8601 UTC"
}
```

## Base URL

All API requests should be made to:

```
https://api.bizzyco.ai/v1
```

<Note>
  Do not include a trailing slash in the base URL. Endpoints are appended
  directly, e.g., `https://api.bizzyco.ai/v1/contacts`.
</Note>

The API is versioned, with `v1` being the current stable version. When breaking
changes are introduced, a new version will be released.

## Request Format

The API accepts JSON-encoded request bodies and returns JSON-encoded responses.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.bizzyco.ai/v1/messages \
    -H "Authorization: Bearer sk_live_abc123..." \
    -H "Content-Type: application/json" \
    -d '{"to": "user@example.com", "subject": "Hello"}'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.bizzyco.ai/v1/messages', {
      method: 'POST',
      headers: {
          Authorization: 'Bearer sk_live_abc123...',
          'Content-Type': 'application/json',
      },
      body: JSON.stringify({
          to: 'user@example.com',
          subject: 'Hello',
      }),
  });

  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.bizzyco.ai/v1/messages',
      headers={
          'Authorization': 'Bearer sk_live_abc123...',
          'Content-Type': 'application/json',
      },
      json={
          'to': 'user@example.com',
          'subject': 'Hello',
      }
  )

  data = response.json()
  ```
</CodeGroup>

### Required Headers

| Header          | Value              | Description                                |
| --------------- | ------------------ | ------------------------------------------ |
| `Authorization` | `Bearer <api-key>` | Your API key for authentication            |
| `Content-Type`  | `application/json` | Required for POST, PUT, and PATCH requests |

### Response Headers

Every authenticated API response includes these headers:

| Header                  | Description                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------- |
| `X-Request-ID`          | Unique identifier for the request. Include this when contacting support for debugging |
| `X-RateLimit-Limit`     | Your plan's per-minute request limit                                                  |
| `X-RateLimit-Remaining` | Requests remaining in the current window                                              |
| `X-RateLimit-Reset`     | Seconds until your allowance is fully replenished                                     |

See [Rate Limits](/api-reference/rate-limits) for per-plan limits and how to
handle `429` responses.

## Shared conventions

Every endpoint in the API follows the same conventions for response shape,
pagination, errors, timestamps, and IDs. Once you've learned them here, you can
skim the resource-specific reference pages without rediscovering them each time.

### Response envelope

All successful responses wrap the payload in a `data` field:

```json theme={null}
{
    "data": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "subject": "Hello",
        "status": "sent",
        "createdAt": "2024-01-15T09:30:00Z",
        "updatedAt": "2024-01-15T09:30:00Z"
    }
}
```

List endpoints add a `meta.pagination` block:

```json theme={null}
{
    "data": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000",
            "subject": "Hello",
            "status": "sent"
        },
        {
            "id": "550e8400-e29b-41d4-a716-446655440001",
            "subject": "Follow-up",
            "status": "draft"
        }
    ],
    "meta": {
        "pagination": {
            "limit": 10,
            "offset": 0,
            "total": 42,
            "hasMore": true
        }
    }
}
```

`hasMore` is computed server-side. `total` is included when the underlying query
can provide it cheaply; otherwise it is omitted and you should rely on `hasMore`
to know when to stop paginating. The request identifier is returned in the
`X-Request-ID` response header, not in the body.

<Note>
  When `total` is omitted, `hasMore` is inferred from whether the page
  returned exactly `limit` items. This means a page that happens to fill
  exactly to `limit` will report `hasMore: true` even if it is the last page —
  your next request will simply return an empty `data` array. Always stop
  paginating when you receive an empty page, not just when `hasMore` becomes
  `false`.
</Note>

### Pagination

List endpoints accept three query parameters:

| Parameter   | Default | Accepted values | Description                              |
| ----------- | ------- | --------------- | ---------------------------------------- |
| `limit`     | 10      | 1–100           | Number of items to return                |
| `offset`    | 0       | ≥ 0             | Number of items to skip                  |
| `sortOrder` | `desc`  | `asc` \| `desc` | Sort direction, typically by `createdAt` |

The API is offset-based; cursor-based pagination is not available today.

```bash theme={null}
curl "https://api.bizzyco.ai/v1/contacts?limit=20&offset=40&sortOrder=asc" \
  -H "Authorization: Bearer sk_live_abc123..."
```

### Error responses

Errors use a single consistent shape:

```json theme={null}
{
    "error": {
        "message": "Validation failed",
        "code": "VALIDATION_ERROR",
        "details": {
            "errors": [],
            "properties": {
                "email": {
                    "errors": ["Invalid email address"]
                }
            }
        }
    }
}
```

`details` is present on validation errors and omitted otherwise. Validation
errors are returned as a tree mirroring the request body: each node has an
`errors` array (issues that apply at that path), and object nodes additionally
have a `properties` map keyed by field name. The top-level `errors` array
carries issues that apply to the request as a whole. Status codes you'll see:

| Status | Meaning                                                  |
| ------ | -------------------------------------------------------- |
| `400`  | Validation error or malformed request                    |
| `401`  | Missing or invalid API key                               |
| `403`  | API key lacks the permissions required for this endpoint |
| `404`  | Resource does not exist (or is soft-deleted)             |
| `429`  | Rate limit exceeded — see the `Retry-After` header       |
| `500`  | Unexpected server error                                  |
| `503`  | Temporarily unavailable (e.g., database outage)          |

See [Error Handling](/api-reference/errors) for the full list of error codes.

### Soft deletes

`DELETE` endpoints perform soft deletes: the record is retained with a
`deletedAt` timestamp set. Soft-deleted records are filtered out of list and get
responses — there is currently no query flag to include them. If you need to
recover a record, contact support.

### Timestamps and IDs

* **Timestamps** are ISO 8601 UTC strings, e.g., `2024-01-15T09:30:00Z`. Every
  resource returns `createdAt` and `updatedAt`, plus a nullable `deletedAt`.
* **Identifiers** are UUID v4 strings (for example,
  `550e8400-e29b-41d4-a716-446655440000`). Every resource uses `id` as its
  primary key, and foreign keys follow the `<resource>Id` convention
  (`contactId`, `businessId`, etc.).

## SDKs

<Note>
  Official SDKs for TypeScript and Python are coming soon. In the meantime,
  you can use the REST API directly with any HTTP client.
</Note>

## OpenAPI Specification

The Bizzy API is documented using OpenAPI 3.1. You can access the specification
at:

```
https://api.bizzyco.ai/v1/openapi.json
```

Use this to generate client libraries, import into API tools like Postman, or
explore the API programmatically.

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    Learn how to create and use API keys
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/api-reference/errors">
    Understand error responses and codes
  </Card>
</CardGroup>
