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

# KODE API fundamentals

> Build reliable KODE API integrations with consistent requests, pagination, rate-limit handling, and error recovery.

Use these conventions across KODE API integrations. Individual endpoint pages document limits or behavior that differ for a specific resource.

## Base URL and version

Version one resources use:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
https://api.kodelabs.com/kodeos/api/v1
```

Build paths from this base URL. Do not remove the `/api/v1` segment.

## Request format

Send and receive JSON unless an endpoint documents another media type.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
Accept: application/json
Content-Type: application/json
Authorization: Bearer <access-token>
```

You do not need `Content-Type` for requests without a body. Attachment endpoints can require `multipart/form-data` or base64-encoded JSON.

## Pagination

List endpoints commonly accept `page` and `limit`.

**page** `integer` (default: 1)

Page number to retrieve. The first page is `1`.

**limit** `integer` (default: 50)

Maximum number of items to return. Some endpoints support up to `200`.

Paginated responses commonly include:

**data** `array` *required*

Resources returned for the current page.

**itemCount** `integer` *required*

Total number of matching resources.

**limit** `integer` *required*

Maximum number of resources returned per page.

**page** `integer` *required*

Current page number.

**pageCount** `integer` *required*

Total number of available pages.

Stop requesting pages when `page` equals `pageCount`. Do not infer completion from a short page when the response provides pagination metadata.

## Rate limits

KODE applies concurrent rolling limits per environment, such as `acme.kodelabs.com`.

| Window | Limit |
| - | -: |
| One second | 5 requests |
| 60 seconds | 100 requests |
| 3,600 seconds | 500 requests |

Every request that reaches the gateway counts, including requests that return `4xx` or `5xx`. Exceeding any window returns `429 Too Many Requests`.

> [!TIP]
>
> Queue requests per environment and add random jitter to retries. This prevents multiple workers from retrying at the same time.

## Retry failed requests

Retry transient failures such as `429`, `502`, `503`, and `504`. Use increasing delays with jitter and a maximum retry count.

Do not automatically retry a write unless you know the operation is safe to repeat. Read the resource after an ambiguous failure before resubmitting a create or update.

```javascript retry.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
const retryableStatuses = new Set([429, 502, 503, 504]);

export async function requestWithRetry(url, options = {}, maxAttempts = 5) {
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
    const response = await fetch(url, options);

    if (response.ok || !retryableStatuses.has(response.status)) {
      return response;
    }

    if (attempt === maxAttempts) {
      throw new Error(`KODE API request failed after ${maxAttempts} attempts: ${response.status}`);
    }

    const delayMs = Math.min(30_000, 500 * 2 ** (attempt - 1));
    const jitterMs = Math.floor(Math.random() * 250);
    await new Promise((resolve) => setTimeout(resolve, delayMs + jitterMs));
  }

  throw new Error("Retry loop ended unexpectedly.");
}
```

## Handle HTTP status codes

| Status | Meaning | Recommended action |
| - | - | - |
| `200 OK` | The request succeeded. | Process the response. |
| `201 Created` | The resource was created. | Store the returned identifier. |
| `400 Bad Request` | The request is invalid. | Correct parameters or the request body. |
| `401 Unauthorized` | Authentication failed or expired. | Request a new token and verify the assertion. |
| `403 Forbidden` | The service lacks access. | Review building and operation permissions. |
| `404 Not Found` | The resource is unavailable. | Verify the identifier and assigned access. |
| `429 Too Many Requests` | A rate-limit window is exhausted. | Back off before retrying. |
| `5xx` | KODE or an upstream service failed. | Retry transient failures with increasing delays. |

Log the HTTP method, path, status, duration, and a correlation identifier when available. Redact tokens, assertions, private keys, and sensitive payload fields.

## Work with identifiers

Treat resource identifiers as opaque strings. Do not parse identifiers or depend on their length and format.

Retrieve identifiers from list or lookup endpoints before calling a dependent endpoint. For example, list buildings before requesting devices for a building.

## Work with time

Use ISO 8601 timestamps where an endpoint accepts date and time strings. Timeseries ingestion endpoints can require Unix epoch timestamps.

Preserve the source timestamp and timezone. Do not substitute the ingestion time for the measurement time.

## Next steps

> [card] [Guides](https://docs.kodelabs.com/products/kode-api/guides/ingest-device-data.md)
>
> Follow end-to-end workflows for common integrations.

> [card] [API reference](https://docs.kodelabs.com/products/kode-api/api-reference/introduction.md)
>
> Browse every endpoint and try requests in the playground.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.