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

# HTTP API

> Here's how you can use the Raindrop API directly, without an SDK

### Base URL

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

### Authentication

All API requests must include your SDK write key in the `Authorization` header:

```
Authorization: Bearer YOUR_WRITE_KEY
```

You can get your API key by logging in to [app.raindrop.ai](https://app.raindrop.ai) (bottom of the tab bar!).

Use your write key for these ingest endpoints. The Query API uses a separate Query API key; see the [Query API reference](/docs/query-api/api-reference).

### Selecting a project

To send data to a specific [project](/docs/platform/projects), include its slug in the `X-Raindrop-Project-Id` header:

```
X-Raindrop-Project-Id: support-prod
```

When the header is omitted, empty, or set to `default`, the request resolves to the default **Production** project, which is the existing behavior. A new slug your org hasn't created yet is accepted and starts collecting data, up to a per-org limit; an archived slug, or a new slug beyond that limit, is rejected with a `403`, and a malformed slug returns a `400`. See [Projects](/docs/platform/projects) for the full behavior table.

### Endpoints

#### Track Event

Track any event, including AI interactions and normal analytics events.

**POST** `/events/track`

**Request Body**

(Must be provided as an array of objects)

| Field | Type | Description |
| - | - | - |
| `user_id` | string | The unique identifier of the user |
| `event` | string | The name of the event you want to track |
| `properties` | object | (Optional) Additional properties associated with the event |
| `attachments` | array | (Optional) Array of attachments to include with the event |
| `ai_data` | object | (Optional) Object containing AI-specific data for AI events. **If provided, either input or output (or both) is required** |
| `ai_data.model` | string | (Optional) The name of the AI model used |
| `ai_data.input` | string | (Optional) The input provided by the user |
| `ai_data.output` | string | (Optional) The output generated by the AI |
| `ai_data.convo_id` | string | (Optional) The conversation ID associated with the interaction |
| `ai_data.tool_calls` | array | (Optional) Tools invoked in this turn. Each item needs a `name`. Arguments, result, status, and timestamps are optional. |

**Example Request - AI Interaction**

One event is one turn: user input, the tools the agent ran, and the assistant output.

```json theme={null}
POST /v1/events/track HTTP/1.1
Host: api.raindrop.ai
Authorization: Bearer YOUR_WRITE_KEY
Content-Type: application/json

[{
  "user_id": "ops-bot",
  "event": "ai_interaction",
  "event_id": "turn_1842",
  "properties": {
    "agent": "checkout-sre"
  },
  "ai_data": {
    "model": "gpt_5",
    "input": "Why did checkout fail for order 1842?",
    "output": "Stripe declined the card (insufficient_funds). I paged #checkout-oncall.",
    "convo_id": "inc-1842",
    "tool_calls": [
      {
        "name": "search_logs",
        "arguments": { "query": "order_id:1842 status:failed", "since": "1h" },
        "result": { "hits": 3, "last_error": "card_declined" },
        "status": "ok",
        "call_id": "call_1"
      },
      {
        "name": "get_order",
        "arguments": { "order_id": "1842" },
        "status": "error",
        "error": "orders API timed out after 5s",
        "call_id": "call_2"
      },
      {
        "name": "get_order",
        "arguments": { "order_id": "1842" },
        "result": { "amount_cents": 4200, "processor": "stripe", "decline_code": "insufficient_funds" },
        "status": "ok",
        "call_id": "call_3"
      },
      {
        "name": "page_oncall",
        "arguments": { "channel": "#checkout-oncall", "order_id": "1842" },
        "result": { "ok": true, "message_ts": "1725120000.000200" },
        "status": "ok",
        "call_id": "call_4"
      }
    ]
  }
}]
```

**Response**

All authorized requests will return a `204 Success` status code. For debugging failures, contact us: [support@raindrop.ai](mailto:support@raindrop.ai).

<Warning>
  Event has a limit of 1 MB. Properties will be truncated for larger events. [Contact us](mailto:support@raindrop.ai) if you have custom requirements.
</Warning>

#### Track Signal

Track positive or negative user signals such as thumbs up, thumbs down, output schema failures, user edits, regenerations, and other ground-truth signals about your AI product's performance. Each signal must be associated with an `event_id` for an event that was sent to Raindrop with the `/events/track` endpoint.

Use `"sentiment": "OTHER"` for label signals that describe an event rather than grade it, such as a user intent (`intent_reorder`). Label signals stay out of positive and negative rates, and you can filter Experiments cohorts by them while keeping the verdict.

**POST** `/signals/track`

**Request Body**

(Must be provided as an array of objects)

| Field | Type | Description |
| - | - | - |
| `event_id` | string | The event\_id of the event that you sent to Raindrop |
| `signal_name` | string | The name of the signal (e.g., "thumbs\_up", "thumbs\_down") |
| `timestamp` | string | (Optional) ISO timestamp when the signal occurred |
| `properties` | object | (Optional) Additional properties associated with the signal |
| `attachment_id` | string | (Optional) Reference to a previously sent attachment |
| `signal_type` | string | (Optional) Type of signal: "default", "feedback", "edit", or "standard" |
| `sentiment` | string | (Optional) "POSITIVE", "NEGATIVE", or "OTHER" ("NEUTRAL" is accepted as "OTHER"). Sets the signal's sentiment when Raindrop first sees its name; change it later on the Signals page |

**Example Request**

```json theme={null}
POST /v1/signals/track HTTP/1.1
Host: api.raindrop.ai
Authorization: Bearer YOUR_WRITE_KEY
Content-Type: application/json

[
{
  "event_id": "123456789",
  "signal_name": "thumbs_up",
  "sentiment": "POSITIVE",
  "properties": {
    "location": "chat_ui"
  },
  "signal_type": "default"
}]
```

**Response**

All authorized requests will return a `204 Success` status code. For debugging failures, contact us: [support@raindrop.ai](mailto:support@raindrop.ai).

#### Identify User

Associate traits with a user.

**POST** `/users/identify`

**Request Body**

| Field | Type | Description |
| - | - | - |
| `user_id` | string | The unique identifier of the user |
| `traits` | object | The traits associated with the user |

**Example Request**

```json theme={null}
POST /v1/users/identify HTTP/1.1
Host: api.raindrop.ai
Authorization: Bearer YOUR_WRITE_KEY
Content-Type: application/json

{
  "user_id": "user123",
  "traits": {
    "name": "John Doe",
    "email": "john@example.com",
    "age": 30,
    "plan": "paid" //we recommend 'free', 'paid', 'trial'
  }
}
```

**Response**

All authorized requests will return a `204 Success` status code. For debugging failures, contact us: [support@raindrop.ai](mailto:support@raindrop.ai).


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