Drains
Model
Fields
Field | Type | Description |
|---|---|---|
object | "drain" | |
id | string | Unique identifier, prefixed with drn_. |
project_id | string | |
team_id | string | |
name | string | |
collection_id | string | null | The collection whose records are forwarded. Null when the drain reads from a view. |
view_id | string | null | The view whose records are forwarded. Null when the drain reads from a collection. |
destination_url | string | The HTTPS URL records are delivered to. |
headers_configured | string[] | Names of the headers sent with every delivery. The values are stored encrypted and are never returned, so this shows what was configured without revealing the secrets. |
body_format | | The shape of each delivered request body. |
compression | | The compression applied to each delivered request body. |
backfill_enabled | boolean | Whether records that already existed when the drain first activated were delivered too. Decided once at first activation and cannot be changed afterwards. |
exclude_fields | string[] | Top-level field names removed from every record before delivery, for destinations that reject fields they do not expect. Empty means nothing is removed. |
status | | Where the drain is in its lifecycle, from unverified through delivering or paused. |
schedule_cron | string | Cron expression setting how often undelivered records are looked for, evaluated in UTC. A drain that is behind keeps delivering without waiting for the next run, so this controls how quickly new records are picked up rather than how fast a backlog clears. |
next_send_at | | null | When the drain is next due to look for records. Null means no time is set rather than nothing
scheduled: on an active drain it is due immediately, and on a stopped one it is ignored.
Whether a drain runs at all is status. |
verified_at | | null | When the destination was proven reachable. Null until the drain is verified. |
last_success_at | | null | When the destination last accepted a delivery. Null if it never has. |
last_failure_at | | null | When a delivery last failed. Null if none ever has. |
consecutive_failure_count | number | How many deliveries have failed in a row. Resets to zero on the next success. |
last_error | string | null | What went wrong on the most recent failed delivery. Null if none ever has. |
last_batch_size | number | How many records were in the most recent successful delivery. |
records_sent_hourly | DrainHourlyRecords[] | The last 24 hours of delivery volume, oldest first. Always 24 entries, so an hour with no deliveries reads as a zero rather than being absent, and a drain that has never sent still returns a full window of zeros. Sum the counts for "records sent in the last 24 hours". |
created_at | | |
updated_at | |
List Drains
Endpoint
Retrieve a list of drains for a project.
/v1/projects/:project_id/drains Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
Query Parameters
Field | Type | Description |
|---|---|---|
order_by | string | Field the results are ordered by. Defaults to "created_at". Accepted values: "name","created_at". |
status | | Return only drains in this state. |
collection_id | string | Return only drains that read from this collection. |
view_id | string | Return only drains that read from this view. |
limit | number | Maximum number of items to return. Defaults to 25. Minimum: 1. Maximum: 200. |
after | string | Cursor from pagination.next_cursor of a previous response. Returns the resources after that page. |
before | string | Cursor from pagination.prev_cursor of a previous response. Returns the resources before that page. |
sort | string | Sort direction for the result set. Defaults to "desc". Accepted values: "asc","desc". |
Comments
afterandbeforeare mutually exclusive.
Response
{
message: string;
data: Drain[];
status: 200;
error: null;
pagination: Pagination;
endpoint: string;
} Retrieve Drain
Endpoint
Retrieve a single drain.
/v1/projects/:project_id/drains/:drain_id Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Response
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Create Drain
Endpoint
Create a drain that forwards records from one collection or view to an external destination.
/v1/projects/:project_id/drains Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
Request Body
Field | Type | Requirement | Description |
|---|---|---|---|
name | string | Required | Name shown for this drain. Minimum length: 2. Maximum length: 128. |
collection_id | string | null | Optional | Collection whose records are forwarded. Set this or view_id, not both. |
view_id | string | null | Optional | View whose records are forwarded. Set this or collection_id, not both. |
destination_url | string | Required | HTTPS URL records are delivered to. Must resolve to a public address. Minimum length: 1. Maximum length: 2048. |
headers | object | null | Optional | Headers sent with every delivery, for authenticating to the destination. Stored encrypted and never returned; responses list only the header names, as headers_configured. |
body_format | | Optional | Shape of each delivered request body. |
compression | | Optional | Compression applied to each delivered request body. |
backfill_enabled | boolean | Optional | Whether records that already existed when the drain first activates are delivered too. Decided once at first activation and cannot be changed afterwards. |
exclude_fields | string[] | Optional | Top-level field names stripped from every record before delivery, for destinations that reject fields they do not expect. |
schedule_cron | string | Optional | Cron expression setting how often undelivered records are looked for, evaluated in UTC. Defaults to hourly. A drain that is behind keeps delivering without waiting for the next run, so this sets how quickly new records are picked up, not how fast a backlog clears. Minimum length: 1. Maximum length: 128. |
Comments
- The destination must be reachable over HTTPS at a public address. Private, loopback and link-local addresses are rejected.
- A new drain starts unverified and sends nothing. Verify it before it delivers records.
- A destination that is Tailglow ingest or a domain this team has verified is trusted, so it skips verification and is activated on create.
- A trusted destination that would write back into the same collection the drain reads from is rejected, because it would loop.
- Exactly one of
collection_idorview_idmust be set. A drain reads from one container. headersaccepts at most 20 entries.exclude_fieldsaccepts at most 50 entries, each a top-level key of at most 256 characters. Dots, whitespace, wildcards and newlines are rejected. Entries are trimmed and duplicates removed.schedule_cronaccepts a five-field expression evaluated in UTC. Second-level precision and hashed fields are rejected; the shortest supported gap is one minute.
Response
{
message: string;
data: Drain;
status: 201;
error: null;
pagination: null;
endpoint: string;
} Update Drain
Endpoint
Update a drain's name, payload format, compression, or excluded fields.
/v1/projects/:project_id/drains/:drain_id Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Request Body
Field | Type | Requirement | Description |
|---|---|---|---|
name | string | Optional | Name shown for this drain. Minimum length: 2. Maximum length: 128. |
body_format | | Optional | Shape of each delivered request body. |
compression | | Optional | Compression applied to each delivered request body. |
exclude_fields | string[] | Optional | Top-level field names stripped from every record before delivery, for destinations that reject fields they do not expect. |
schedule_cron | string | Optional | Cron expression setting how often undelivered records are looked for, evaluated in UTC. Defaults to hourly. A drain that is behind keeps delivering without waiting for the next run, so this sets how quickly new records are picked up, not how fast a backlog clears. Minimum length: 1. Maximum length: 128. |
Comments
destination_url,headersandbackfill_enabledcannot be changed. Changing the URL or headers would invalidate the proof of access established at verification, and backfill is decided once when the drain first activates. Delete the drain and create a new one instead.- At least one field must be provided.
- Any field not listed here is rejected, including
destination_url,headersandbackfill_enabled, which cannot be changed after create. exclude_fieldsaccepts at most 50 entries, each a top-level key of at most 256 characters. Dots, whitespace, wildcards and newlines are rejected. Entries are trimmed and duplicates removed.schedule_cronaccepts a five-field expression evaluated in UTC. Second-level precision and hashed fields are rejected; the shortest supported gap is one minute.
Response
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Delete Drain
Endpoint
Delete a drain and stop all delivery to its destination.
/v1/projects/:project_id/drains/:drain_id Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Response
{
message: string;
data: null;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Verify Drain
Endpoint
Send a verification marker to the drain's destination and return the destination's response.
/v1/projects/:project_id/drains/:drain_id/verify Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Comments
- Proving control of the destination takes two steps. This one delivers a marker token to the destination; read that token from what the destination received and send it back to
verify_confirm. - The marker token is never included in this response. Reading it from the destination is what proves access, so echoing it here would defeat the check.
- A destination that has since become trusted infrastructure is activated immediately and returns the drain with no marker sent.
- The
responsefield reports what the destination replied with, including non-2xx statuses, so a misconfigured endpoint can be diagnosed without reading logs.
Response 200 (1)
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Response 200 (2)
{
message: string;
data: { drain: Drain; response: { status: number; status_text: string; ok: boolean; response_time_ms: number; body_preview: string; } };
status: 200;
error: null;
pagination: null;
endpoint: string;
} Additional Response Fields
Field | Type |
|---|---|
drain | |
response | { status: number; status_text: string; ok: boolean; response_time_ms: number; body_preview: string; } |
Confirm Drain Verification
Endpoint
Confirm a drain by sending back the marker token the destination received.
/v1/projects/:project_id/drains/:drain_id/verify_confirm Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Request Body
Field | Type | Requirement | Description |
|---|---|---|---|
token | string | Required | The marker token the destination received from the verify request. Minimum length: 1. Maximum length: 128. |
Comments
- Send the token that arrived at the destination from
verify. A correct token activates the drain and it begins delivering records.
Response
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Pause Drain
Endpoint
Pause a drain so it stops delivering records without losing its verification.
/v1/projects/:project_id/drains/:drain_id/pause Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Comments
- A paused drain keeps its position, so resuming continues from where it stopped rather than re-sending or skipping records.
Response
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Resume Drain
Endpoint
Resume a paused drain and continue delivering records from where it stopped.
/v1/projects/:project_id/drains/:drain_id/resume Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Response
{
message: string;
data: Drain;
status: 200;
error: null;
pagination: null;
endpoint: string;
} Send Drain Sample
Endpoint
Send a sample payload to the drain's destination and return the destination's response.
/v1/projects/:project_id/drains/:drain_id/sample Path Parameters
Field | Type | Description |
|---|---|---|
project_id | string | Unique identifier of the project. |
drain_id | string | Unique identifier of the drain. |
Comments
- Use this to check the destination accepts the payload shape before or after activating the drain. The sample is not part of the record stream and does not move the drain's position.
- A non-2xx reply is returned rather than raised, so the status and body preview can be read directly from the response.
Response
{
message: string;
data: { status: number; status_text: string; ok: boolean; response_time_ms: number; body_preview: string };
status: 200;
error: null;
pagination: null;
endpoint: string;
} Additional Response Fields
Field | Type |
|---|---|
status | number |
status_text | string |
ok | boolean |
response_time_ms | number |
body_preview | string |
Referenced Types
ISODateString
An ISO 8601 date-time string returned at the JSON API boundary.