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

# API overview

> How the Keen API works — action-based requests, authentication, and error handling.

import ApiAuth from "/_snippets/api-auth.mdx";
import BaseUrl from "/_snippets/base-url.mdx";

## Action-based design

The Keen API is **not** a traditional REST API with separate URLs per resource. Instead, every request is a `POST` to a single URL. The `action` field in the JSON body determines the operation.

<BaseUrl />

## Authentication

<ApiAuth />

The `lead_external` action is the only exception — it does not require an API key. Instead, it relies on a channel-level setting that enables public lead submission.

## Request format

Every request must be `POST` with a `Content-Type: application/json` header. The body must include an `action` field and any additional fields required by that action.

```bash theme={null}
curl -X POST https://data.keenpartner.com/functions/v1/keen-api \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -d '{"action": "get_channels"}'
```

## Available actions

| Action                                                          | Purpose                                                                            |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| [`get_channels`](/api-reference/get-channels)                   | List channels accessible to your company                                           |
| [`get_leads`](/api-reference/get-leads)                         | List leads for a channel                                                           |
| [`get_lead_by_legacy_id`](/api-reference/get-lead-by-legacy-id) | Look up a single lead by its legacy integer ID                                     |
| [`create_lead`](/api-reference/create-lead)                     | Create a new lead in a channel                                                     |
| [`update_status`](/api-reference/update-status)                 | Update a lead's status by name                                                     |
| [`update_status_id`](/api-reference/update-status-id)           | Update a lead's status by ID                                                       |
| [`create_purchase`](/api-reference/create-purchase)             | Record a purchase against a lead and optionally control which reward triggers fire |
| [`lead_external`](/api-reference/lead-external)                 | Create a lead without authentication                                               |

## Channel access

Your API key is scoped to a single company. You can only interact with channels where your company is the creator, partner, referring company, or receiving company.

If you attempt to access a channel your company is not part of, the API returns a `403` error.

## Error responses

All errors return JSON with an `error` field:

```json theme={null}
{
  "error": "Channel not accessible"
}
```

| Status code | Meaning                                                             |
| ----------- | ------------------------------------------------------------------- |
| `400`       | Bad request — missing or invalid fields                             |
| `401`       | Invalid API key                                                     |
| `403`       | Your company does not have access to the requested resource         |
| `404`       | Resource not found (e.g. status name does not exist on the channel) |
| `500`       | Internal server error                                               |
