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.

GET
/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

  • after and before are mutually exclusive.

Response

200
{
  message: string;
  data: Drain[];
  status: 200;
  error: null;
  pagination: Pagination;
  endpoint: string;
}

Retrieve Drain

Endpoint

Retrieve a single drain.

GET
/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

200
{
  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.

POST
/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_id or view_id must be set. A drain reads from one container.
  • headers accepts at most 20 entries.
  • exclude_fields accepts 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_cron accepts a five-field expression evaluated in UTC. Second-level precision and hashed fields are rejected; the shortest supported gap is one minute.

Response

201
{
  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.

POST
/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, headers and backfill_enabled cannot 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, headers and backfill_enabled, which cannot be changed after create.
  • exclude_fields accepts 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_cron accepts a five-field expression evaluated in UTC. Second-level precision and hashed fields are rejected; the shortest supported gap is one minute.

Response

200
{
  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.

DELETE
/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

200
{
  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.

POST
/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 response field reports what the destination replied with, including non-2xx statuses, so a misconfigured endpoint can be diagnosed without reading logs.

Response 200 (1)

200
{
  message: string;
  data: Drain;
  status: 200;
  error: null;
  pagination: null;
  endpoint: string;
}

Response 200 (2)

200
{
  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.

POST
/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

200
{
  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.

POST
/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

200
{
  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.

POST
/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

200
{
  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.

POST
/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

200
{
  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.

DrainBodyFormat

ndjson
json

DrainCompression

none
gzip

DrainStatus

draft
pending_verification
active
paused
disabled