@tailglow/cli 0.6.4 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/docs.generated.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailglow/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Tailglow command line. Every command is generated from the Tailglow API reference, so the CLI and the documentation can never describe different APIs.",
|
|
6
6
|
"bin": {
|
package/src/docs.generated.js
CHANGED
|
@@ -16,7 +16,7 @@ export const DOCS_PAGES = {
|
|
|
16
16
|
"api/introduction": "# Introduction\n\n## Base URL\n\nThe Tailglow API is built on REST principles. We enforce HTTPS in every request to improve data security, integrity, and privacy. The API does not support HTTP.\n\nAll requests contain the following base URL:\n\n```md\nhttps://api.tailglow.io\n```\n\n## Authentication\n\nTo authenticate with the Tailglow API, send your API key in the `Authorization` header using the `Bearer` scheme. An API key looks like `tg_api_` followed by 70 characters.\n\n```md\nAuthorization: Bearer tg_api_1a2B3c4D5e6F7g8H9i0J...\n```\n\n`Authorization: Key <your key>` is also accepted, as is sending the key on its own with no scheme. Keys issued before the `tg_api_` prefix begin with `sk_` and keep working indefinitely.\n\n## Filtering Data\n\nWhen filtering data, you'll create a query string that will be appended to the URL of your `GET` request. The query string will begin with a `?` and contain key-value pairs separated by `&`.\n\n```\nBe careful when using \"not\" filters. They can result in a lot of data being returned.\n```\n\nTailglow uses a single canonical operator vocabulary across every filter surface. URL syntax is flat: `?<field>=<op>:<value>`. The full list, per-type allowlists, and per-surface availability matrix live in the [Filter Operators enum](/api/enums#filter-operators).\n\n### Strings\n\n- **`equals`** - `?type=equals:expense`\n- **`not_equals`** - `?type=not_equals:expense`\n- **`starts_with`** - `?type=starts_with:expense`\n- **`not_starts_with`** - `?type=not_starts_with:expense`\n- **`ends_with`** - `?type=ends_with:expense`\n- **`not_ends_with`** - `?type=not_ends_with:expense`\n- **`contains`** - `?type=contains:expense`\n- **`not_contains`** - `?type=not_contains:expense`\n- **`in`** - `?type=in:expense,refund`\n- **`not_in`** - `?type=not_in:expense,refund`\n\nString operators compare case-insensitively, so `?type=equals:GET` and `?type=equals:get` include the same rows.\n\n### Numbers\n\n- **`equals`** - `?value=equals:100`\n- **`not_equals`** - `?value=not_equals:100`\n- **`gt`** (Greater Than) - `?value=gt:100`\n- **`gte`** (Greater Than or Equal) - `?value=gte:100`\n- **`lt`** (Less Than) - `?value=lt:100`\n- **`lte`** (Less Than or Equal) - `?value=lte:100`\n- **`between`** - `?value=between:100,200`\n- **`in`** / **`not_in`** - `?value=in:100,200`\n\n## Pagination\n\nMost `list` endpoints use cursor-based pagination. The first request omits the cursor; subsequent requests echo back the `next_cursor` (or `prev_cursor`) the previous response handed you.\n\n### Request parameters\n\n- **`limit`** `number`\n Maximum number of items to return per page. Defaults to `25`, max `200`.\n- **`after`** `string`\n Opaque cursor from a previous response's `pagination.next_cursor`. Returns the rows after the pivot.\n- **`before`** `string`\n Opaque cursor from a previous response's `pagination.prev_cursor`. Returns the rows before the pivot. Mutually exclusive with `after`.\n- **`sort`** `\"asc\" \\| \"desc\"`\n Sort direction. Cursors are minted under one direction; reusing them under a different sort returns a `400`.\n\n### Response shape\n\nThe `pagination` object on every list response carries:\n\n- **`limit`** `number`: echoed from the request.\n- **`count`** `number`: number of rows in this page (≤ `limit`).\n- **`offset`** `number`: 0-indexed position of the first row across the full result set. Use `offset + 1` for \"Showing 21\" labels.\n- **`sort`** `\"asc\" \\| \"desc\"`: echoed sort direction.\n- **`next_cursor`** `string \\| null`: cursor for the next page. `null` means there are no more rows.\n- **`prev_cursor`** `string \\| null`: cursor for the previous page. `null` means you're on the first page.\n- **`total`** `number \\| null`: exact row count for database-backed lists and records. `null` is returned only when the underlying feed cannot provide a total. For example, collection docs always return `null` because the underlying files aren't enumerated.\n\nCursors are server-minted opaque tokens. Don't construct them yourself; round-trip the values the API gave you.\n\n## Responses\n\nAll of our responses will follow a standard structure, regardless if it's successful or not. Here is an example of the response object.\n\n### Successful Response Example\n\nIf you are listing data, the `data` key will be an array of objects and a pagination object will be present.\nIf you are retrieving, creating, or writing a single object, the `data` key will be an object.\nIf you are deleting an object, the `data` key will be `null`.\n\n```json\n{\n \"message\": \"Data retrieved successfully\",\n \"data\": [],\n \"status\": 200,\n \"error\": null,\n \"pagination\": {\n \"object\": \"pagination\",\n \"limit\": 10,\n \"count\": 10,\n \"offset\": 0,\n \"sort\": \"desc\",\n \"next_cursor\": \"eyJ2IjoxLCJyZXNvdXJjZSI6...\",\n \"prev_cursor\": null,\n \"total\": 42\n },\n \"endpoint\": \"/v1/projects\"\n}\n```\n\n### Error Response Example\n\nYou'll typically see error when request validations fail. The `error` key will contain an object with a `code` key and a `properties` key that will contain an array of objects with an `id` and `message` key. The `id` corresponds to the field that failed validation and the `message` will contain the error message.\n\n```json\n{\n \"message\": \"The request is invalid\",\n \"data\": null,\n \"status\": 400,\n \"error\": {\n \"code\": \"request_invalid\",\n \"properties\": [\n {\n \"id\": \"name\",\n \"message\": \"Name is required\"\n }\n ]\n },\n \"pagination\": null,\n \"endpoint\": \"/v1/projects\"\n}\n```\n",
|
|
17
17
|
"api/errors": "# Errors\n\n## Variations\n\nWe follow standard HTTP status codes for errors. Here are the variations you might encounter:\n\n### `request_invalid`\n\n- **Status Code:** 400\n- **Message:** \"The request is invalid.\"\n- **How to Resolve:** Check the request payload for missing or incorrect fields.\n\n### `request_no_update`\n\n- **Status Code:** 400\n- **Message:** \"There was nothing new to update.\"\n- **How to Resolve:** Make sure you're submitting new or modified data.\n\n### `request_validation_failed`\n\n- **Status Code:** 400\n- **Message:** \"The request failed validation.\"\n- **How to Resolve:** Ensure all fields meet the required validation rules.\n\n### `unsupported_file_type`\n\n- **Status Code:** 400\n- **Message:** \"Unsupported file type.\"\n- **How to Resolve:** Use one of the supported file formats.\n\n### `auth_missing_credentials`\n\n- **Status Code:** 401\n- **Message:** \"You must provide credentials to access this resource.\"\n- **How to Resolve:** Include your API key in the `Authorization` header.\n\n### `auth_invalid_credentials`\n\n- **Status Code:** 401\n- **Message:** \"Your credentials are invalid.\"\n- **How to Resolve:** Double-check your API key or token.\n\n### `auth_account_disabled`\n\n- **Status Code:** 401\n- **Message:** \"Your account is disabled, please contact support.\"\n- **How to Resolve:** Reach out to support to restore access.\n\n### `auth_missing_permissions`\n\n- **Status Code:** 401\n- **Message:** \"You do not have permission to access this resource.\"\n- **How to Resolve:** Ensure your account has the appropriate permissions.\n\n### `auth_mfa_required`\n\n- **Status Code:** 401\n- **Message:** \"Multi-factor authentication is required.\"\n- **How to Resolve:** Complete MFA verification before accessing this resource.\n\n### `auth_unavailable`\n\n- **Status Code:** 503\n- **Message:** \"Your credentials could not be checked right now; retry shortly.\"\n- **Returned by:** any authenticated endpoint when Tailglow cannot reach a service it needs to check your credentials. Your credentials have not been rejected, and nothing about the request needs to change.\n- **How to Resolve:** Retry the request after a short wait. Do not sign out or replace your API key: this error is temporary.\n\n### `resource_limit_reached`\n\n- **Status Code:** 403\n- **Message:** \"You have reached the limit for this resource.\"\n- **How to Resolve:** Upgrade your plan or wait until the limit resets.\n\n### `forbidden`\n\n- **Status Code:** 403\n- **Message:** \"This action is forbidden.\"\n- **How to Resolve:** Ensure you have proper permissions for this action.\n\n### `resource_not_found`\n\n- **Status Code:** 404\n- **Message:** \"The requested resource was not found.\"\n- **How to Resolve:** Verify the resource ID or endpoint.\n\n### `request_timeout`\n\n- **Status Code:** 408\n- **Message:** \"The request timed out.\"\n- **How to Resolve:** Retry the request or check your connection.\n\n### `rate_limit_exceeded`\n\n- **Status Code:** 429\n- **Message:** \"You have exceeded the rate limit.\"\n- **How to Resolve:** Reduce the frequency of your requests and try again later.\n\n### `resource_locked`\n\n- **Status Code:** 409\n- **Message:** \"The resource is locked.\"\n- **How to Resolve:** Unlock the resource if possible or wait until it becomes available.\n\n### `payload_too_large`\n\n- **Status Code:** 413\n- **Message:** \"The payload was too large for the server to safely handle.\"\n- **How to Resolve:** Reduce the size of the request payload.\n\n### `ingest_spool_full`\n\n- **Status Code:** 503\n- **Message:** \"Server at capacity (REASON); retry shortly\", where REASON names the limiting resource, e.g. a disk-capacity reason such as \"N MiB free below the M MiB byte floor\" or \"inodes P% at/above the C% ceiling\", \"ingest queue full\", or \"storage write failed\".\n- **Returned by:** the ingest endpoint when the server's durable spool cannot accept more records. The response includes a `Retry-After` header (in seconds).\n- **How to Resolve:** Retry the request after the `Retry-After` interval. If the error persists, you've outgrown the server's allocated capacity for this project. Provision a larger spool volume or distribute traffic across additional servers.\n\n### `ingest_auth_unavailable`\n\n- **Status Code:** 503\n- **Message:** \"The ingest key could not be verified; retry shortly.\"\n- **Returned by:** the ingest endpoint when it cannot reach the service that verifies ingest keys. Your key has not been rejected, and nothing about the request needs to change. The response includes a `Retry-After` header (in seconds).\n- **How to Resolve:** Retry the request after the `Retry-After` interval. Tailglow SDKs do this automatically. A key that was verified recently keeps being accepted throughout the outage, so this only affects a key the server has not seen lately.\n\n### `database_error`\n\n- **Status Code:** 500\n- **Message:** \"A database error occurred.\"\n- **How to Resolve:** Try again later or contact support if the issue persists.\n\n### `invalid_server_state`\n\n- **Status Code:** 500\n- **Message:** \"The server is in an invalid state.\"\n- **How to Resolve:** Contact support if the issue persists.\n\n### `plan_limit_reached`\n\n- **Status Code:** 403\n- **Message:** \"You have reached the limit for your current plan.\"\n- **How to Resolve:** Upgrade your plan to increase your limits.\n\n### `server_error`\n\n- **Status Code:** 500\n- **Message:** \"An error occurred.\"\n- **How to Resolve:** Try again later or contact support if the issue persists.\n\n### `not_implemented`\n\n- **Status Code:** 501\n- **Message:** \"This route has not been implemented.\"\n- **How to Resolve:** Contact support or refer to the documentation for available routes.\n",
|
|
18
18
|
"api/enums": "# Enums\n\nThis page lists common enum values used across the API.\n\n## Metric Group By\n\nThe `group_by` field accepts any string field names from your view's output schema. There is no fixed set of allowed values.\n\n## Chart Types\n\n- `line`\n- `area`\n- `bar`\n- `pie`\n- `scatter`\n- `radar`\n- `stat`\n- `gauge`\n- `calendar`\n- `uptime`\n\n## Chart Color Modes\n\nHow a chart picks colors. The chart type must allow the chosen mode (e.g., gauge supports `by_series` and `by_value`; calendar supports `by_series` and `by_intensity`).\n\n- `by_series`: Each series gets its own color. Colors are auto-assigned from a deterministic series-hash → palette projection (stable across drill-down). Per-series overrides via [Update Series](/api/metrics#update-series).\n- `by_intensity`: One base color (`ui_chart_color_base`); the renderer modulates lightness/opacity by value. Used by calendar / heatmap-style charts.\n- `by_value`: Ordered rules (`ui_chart_color_rules`) map each value to a color. First matching rule wins; no match falls back to system default. Used by gauges and uptime strips.\n\n## Metric Chart Values\n\nDetermines which aggregation is displayed by default on a chart.\n\n- `count`: Number of records.\n- `average`: Average of the record `value` field.\n- `sum`: Sum of the record `value` field.\n- `min`: Minimum of the record `value` field.\n- `max`: Maximum of the record `value` field.\n- `last`: Latest reading in each time bucket per group_by combination. Within the requested range, the last observed value carries forward across complete empty intervals. Use for entity/snapshot data (e.g., deals, users, inventory).\n- `cumulative_sum`: Cumulative sum of the record `value` field over the time range.\n- `cumulative_count`: Cumulative count of records over the time range.\n- `p50`: 50th percentile (median) of the record `value` field.\n- `p95`: 95th percentile of the record `value` field.\n- `p99`: 99th percentile of the record `value` field.\n- `count_unique`: Number of distinct values of the `unique_field`. Exact for small cardinalities (up to 8,192), approximate for larger sets.\n\n## Empty Bucket Handling\n\nControls how time intervals with no data render on a metric's chart. This is a display setting: changing it applies instantly to all historical data with no recalculation.\n\n- `zero`: Empty intervals render as a true 0. The right choice for additive aggregations (`count`, `sum`, `cumulative_*`, `count_unique`) where \"nothing happened\" means zero. Monitors evaluate an empty window as 0, so conditions like `count == 0` can trigger.\n- `gaps`: Empty intervals render as gaps (`null` values in `series.records`) and are excluded from trend line fitting. The right choice for observational aggregations (`average`, `min`, `max`, percentiles) where an empty interval has no defined value. Monitors skip evaluation when a series has no data in the window: nothing fires and open alerts stay open until data returns. The `last` chart value is the one exception on charts: it carries the latest measured value forward through empty intervals in both modes.\n\nNew metrics default based on their `ui_chart_value`: additive aggregations get `zero`, observational aggregations get `gaps`.\n\n## Chart Colors\n\nPossible values for the `color` property within `ui_chart_colors`.\n\n- `blue`\n- `red`\n- `amber`\n- `green`\n- `teal`\n- `purple`\n- `pink`\n\n## Analytics Time Ranges\n\nUsed for `time_range` (in aggregation requests) and `ui_chart_time_range` (in the metric object).\n\n- `last_hour`\n- `last_6_hours`\n- `today`\n- `last_24_hours`\n- `yesterday`\n- `this_week`\n- `last_7_days`\n- `last_week`\n- `this_month`\n- `last_30_days`\n- `last_month`\n- `this_quarter`\n- `last_90_days`\n- `last_quarter`\n- `this_year`\n- `last_365_days`\n- `last_year`\n- `all_time`\n- `custom` (Requires specific start/end dates)\n- `next_7_days`\n- `next_30_days`\n- `next_90_days`\n\nA `next_*` range reaches the same distance into the past as it does into the future, so a chart has history to fit a forecast from.\n\n## Forecast Horizons\n\nUsed for `ui_chart_forecast_horizon` (in the metric object). Relative values resolve when the chart is viewed.\n\n- `next_7_days`\n- `next_30_days`\n- `next_90_days`\n- `end_of_quarter`\n- `end_of_year`\n- `next_year`\n\n## Forecast Models\n\nUsed for `ui_chart_forecast_model` (in the metric object). `auto` follows whichever model fits the data best.\n\n- `auto`\n- `linear`\n- `exponential`\n- `logarithmic`\n- `logistic`\n- `sinusoidal`\n\n## Metric Data Intervals\n\nUsed for `interval` (in aggregation requests) and `ui_chart_interval` (in the metric object).\n\n- `minute`\n- `hour`\n- `day`\n- `month`\n\n## View Transform Modes\n\nHow a [View](/api/views#model) acquires a [TGL](/guides/tgl) transform for schema versions discovered after it was created.\n\nBoth modes first try to reuse one of the view's existing scripts. Reuse requires a typed candidate signature and at least one of the script's read paths to be present. A present path whose value is null counts as evidence; an absent path does not. An unknown-only signature is not eligible for reuse. The modes differ only when no existing script can read the new shape:\n\n- `auto`: Tailglow generates a script for the new version.\n- `manual`: The version waits for you to supply a compatible script instead of generating one automatically. A supplied script can wait for input before validation.\n\n## View Transform Conflict Resolutions\n\nControls what happens when editing a collection-backed transform would make the new script incompatible with some schema versions that used the prior script.\n\n- `strand`: Default. Compatible versions adopt the edit; conflicting versions move to queued placeholders so they can receive their own script.\n- `keep`: Compatible versions adopt the edit; conflicting versions remain on the prior script.\n\n## Schema Version States\n\nThe lifecycle of a collection's [schema version](/guides/concepts#schema-versions), from first sight to trust.\n\n- `candidate`: The shape has been seen once. Its records are stored and served immediately by any view mapping that already fits them, but no mapping is written for it yet.\n- `settled`: The shape was seen again after the collection's recurrence gap, arrived in one batch with at least the bulk row count, or a person settled it. Only settled versions are offered to views for authoring, and a settled version never goes back.\n- `stale`: A candidate that was not seen again within the stale window. Its rows stay stored but unclassified. A stale shape that returns settles.\n\n## Schema Settlements\n\nWhat settled a schema version.\n\n- `recurrence`: The shape was seen again after the collection's recurrence gap.\n- `bulk`: One batch carried at least the collection's bulk row count of the shape.\n- `person`: Someone settled the version from the collection page or through the API.\n\n## Schema Rule Modes\n\nHow a collection applies each of its three identity rules: nulls and absent values, optional keys, and the detector. See [Schema settings](/guides/sources#schema-settings).\n\n- `auto`: Tailglow decides. Null and absent values are accepted at any path a mapping reads, a record whose keys are a subset of a version's keys joins that version, and a safe opaque-path proposal from the detector is applied on its own.\n- `manual`: A person decides at each of those points.\n\n## Metric Statuses\n\nThe current status of the metric.\n\n- `initializing`: Metric is being created.\n- `waiting_for_transforms`: Metric is waiting for its source transforms to finish processing.\n- `backfilling`: Historical data is being backfilled (also covers re-backfill triggered by data-feed changes).\n- `active`: Metric is up-to-date and collecting new data.\n- `error`: An error occurred during processing.\n- `cancelled`: The metric, or the view it reads, was deleted while a backfill was still running, so the backfill was cancelled instead of being allowed to finish. Restoring the metric within its 24-hour window leaves it here; re-run the backfill to finish what it missed.\n\n## View Statuses\n\nThe current status of a [View](/api/views#model), derived from its transforms.\n\n- `empty`: The view has no transforms yet.\n- `building`: A transform is waiting for input or processing data, including indexing history.\n- `needs_transform`: A transform script needs to be written or corrected. This can occur in either transform mode.\n- `active`: At least one transform is finished and serving data.\n- `cancelled`: The view was deleted while it was still indexing, so the indexing was cancelled rather than allowed to finish. Deleted views remain readable until permanent removal 24 hours later, and they report this status for that window.\n- `error`: A transform failed to compile, or its indexing failed.\n\n## Metric Values\n\nIndicates which aggregations were calculated in the [Metric Aggregation Model](/api/metrics#aggregation-model).\n\n- `count`\n- `sum`\n- `min`\n- `max`\n\n## Filter Operators\n\nThe canonical operator vocabulary used everywhere filters appear: list endpoint query parameters (`?<field>=<op>:<value>`), metric `filters` (applied at rollup time), facet record queries against indexed views, and the UI filter components.\n\nURL syntax is flat: `?type_1=equals:Fire&limit=50`. Operator names are long-form snake*case except for the industry-standard `gt`/`gte`/`lt`/`lte`/`in`. Every negation has a `not*` prefix. String operators compare case-insensitively (`equals:Get`matches`GET`); numeric, date, and existence operators are unaffected.\n\n| Operator | Semantics |\n| ----------------- | --------------------------------------------- |\n| `equals` | Exact match |\n| `not_equals` | Inverse of `equals` |\n| `gt` / `gte` | Greater than (strict / inclusive) |\n| `lt` / `lte` | Less than (strict / inclusive) |\n| `between` | Inclusive range; value is `min,max` |\n| `contains` | Substring match (strings) |\n| `not_contains` | Inverse of `contains` |\n| `starts_with` | Prefix match (strings) |\n| `not_starts_with` | Inverse of `starts_with` |\n| `ends_with` | Suffix match (strings) |\n| `not_ends_with` | Inverse of `ends_with` |\n| `in` | Scalar field, value in a comma-separated list |\n| `not_in` | Inverse of `in` |\n| `has` | Array field contains the given scalar |\n| `not_has` | Inverse of `has` |\n| `has_any` | Array field intersects a comma-separated list |\n| `exists` | Field has a non-null value |\n| `not_exists` | Field is null or absent |\n\n### Per-type allowlist (UI filter components)\n\n| Field type | Allowed operators |\n| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |\n| `string` | `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `not_starts_with`, `ends_with`, `not_ends_with`, `in`, `not_in` |\n| `number` | `equals`, `not_equals`, `gt`, `gte`, `lt`, `lte`, `between`, `in`, `not_in` |\n| `date` | `equals`, `not_equals`, `gt`, `gte`, `lt`, `lte`, `between` |\n| `array` | `has`, `not_has`, `has_any` |\n| `boolean` | `equals`, `not_equals` |\n\n### Surface availability\n\nNot every operator is supported by every surface. The metric filter pipeline supports the full vocabulary; CRUD list endpoints reject existence operators in v1 (the per-field nullable-aware validators land separately); facet record queries are limited to the SQLite-indexed subset.\n\n| Operator | Metric filters | CRUD list | Facet records |\n| ----------------- | :------------: | :-------: | :-----------: |\n| `equals` | ✓ | ✓ | ✓ |\n| `not_equals` | ✓ | ✓ | |\n| `gt` | ✓ | ✓ | |\n| `gte` | ✓ | ✓ | ✓ |\n| `lt` | ✓ | ✓ | |\n| `lte` | ✓ | ✓ | ✓ |\n| `between` | ✓ | ✓ | |\n| `contains` | ✓ | ✓ | |\n| `not_contains` | ✓ | ✓ | |\n| `starts_with` | ✓ | ✓ | ✓ |\n| `not_starts_with` | ✓ | ✓ | |\n| `ends_with` | ✓ | ✓ | |\n| `not_ends_with` | ✓ | ✓ | |\n| `in` / `not_in` | ✓ | ✓ | |\n| `has` | ✓ | | |\n| `not_has` | ✓ | | |\n| `has_any` | ✓ | | |\n| `exists` | ✓ | | |\n| `not_exists` | ✓ | | |\n\n### Reserved query parameter keys\n\nSeveral keys are reserved as query-string control parameters across every endpoint. View `output_schema` fields and facet `field_path` values cannot use any of these names:\n\n`limit`, `cursor`, `page`, `sort`, `order_by`, `after`, `before`, `start_at`, `end_at`, `timezone`, `interval`, `search`\n\n## Monitor Condition Types\n\n| Value | Meaning |\n| --- | --- |\n| `threshold` | Compare the selected metric value with a threshold. |\n| `sustained` | Require that comparison to hold for a duration. |\n| `existence` | Fire when the selected value is greater than zero. |\n| `absence` | Fire when a complete evaluation window contains no observations, even on a chart that displays gaps. Requires Count and a finite window. |\n\nFor absence, Total watches the whole filtered feed. Any series and Each series watch known individual series. A measured value of zero is still an observation. Unknown completeness postpones evaluation.\n\n## Drain Statuses\n\nLifecycle status of a Drain.\n\n- `draft`: Created but never verified. No outbound traffic.\n- `pending_verification`: A verification marker has been sent to the destination and we're waiting for the customer to paste it back via Confirm Verification.\n- `active`: Drain is verified, resumed, and forwarding records on the recurring schedule.\n- `paused`: You stopped the drain, or it was freshly verified (verification intentionally lands paused so you can sample before going live). Only you start it again. Resume via Resume Drain.\n- `disabled`: Tailglow stopped the drain after 72 hours of consecutive failures. Resume the same way after fixing the destination; resuming clears the failure counters.\n\n## Drain Body Formats\n\nWire format for the body of outbound drain POSTs.\n\n- `ndjson`: Newline-delimited JSON. Default. One record per line. Sent with `Content-Type: application/x-ndjson`.\n- `json`: A single JSON array of records. Required by Datadog Logs and similar receivers. Sent with `Content-Type: application/json`.\n\n## Drain Compressions\n\nWire compression for outbound drain POSTs.\n\n- `none`: Default. Body is sent uncompressed and works with any receiver.\n- `gzip`: Body is gzipped and `Content-Encoding: gzip` is added. Receivers MUST decompress `Content-Encoding` for this to work.\n\n## Check Statuses\n\nLifecycle status of a Check ([`status`](/api/checks#model)).\n\n- `active`: Running on its schedule.\n- `paused`: You stopped the check. Nothing is recorded for the minutes a pause covers, so the uptime record shows a gap rather than downtime. Start it again with Resume Check.\n- `disabled`: Tailglow stopped the check because the team is no longer in good standing. A failing endpoint never lands here, however long the failure lasts, because the outage is the thing the check exists to record. Resume the same way once the account is settled.\n\n## Check Methods\n\nThe HTTP method a check uses to request its endpoint ([`method`](/api/checks#model)). Both are observational, so a check can never change anything at the endpoint it watches.\n\n- `get`: Default.\n- `post`: For health endpoints that only answer to POST. Only a `post` check may send a `request_body`.\n\n## Check Error Stages\n\nWhich step of the most recent failed run went wrong ([`last_error_stage`](/api/checks#model)). A check never reads the response body, so there is no parse stage.\n\n- `request`: No usable response arrived. The address was refused by the outbound guard, the request timed out, TLS failed, the connection was reset, or the body ran past the size cap before it finished.\n- `response`: The endpoint answered, but not with a 2xx status.\n\n## Appearance Palettes\n\nThe color palette for a user's app appearance ([`appearance_palette`](/api/users#model)). Sets the light or dark scheme.\n\n- `light`\n- `dark`\n- `dim`: Default. A softer dark scheme.\n- `midnight`\n- `paper`\n\n## Appearance Type Sets\n\nThe font pairing for a user's app appearance ([`appearance_type_set`](/api/users#model)).\n\n- `system`: Default. The operating system's native font stack.\n- `grotesk`\n- `editorial`\n- `geometric`\n\n## Appearance Accents\n\nThe accent color for a user's app appearance ([`appearance_accent`](/api/users#model)).\n\n- `orange`: Default.\n- `azure`\n- `burgundy`\n- `ink`\n- `emerald`\n- `violet`\n\n## Appearance Scales\n\nThe UI scale (density) for a user's app appearance ([`appearance_scale`](/api/users#model)). Applies at tablet and desktop widths; mobile always renders at full size.\n\n- `comfortable`: 100% scale.\n- `cozy`: 90% scale.\n- `compact`: Default. 80% scale, fits more on screen.\n\n## Ingest Pipeline Error Reasons\n\nThe reasons behind the Errors series on a server's Ingest Pipeline chart. Every reason is a refusal issued before acceptance: the sender received an error response and nothing was recorded from that request. Accepted data is never dropped. It is queued on the server and retried until it lands.\n\nReasons where retrying the same request delivers the data. Tailglow SDKs retry these automatically; if you send raw HTTP, retry on any 5xx response:\n\n- `connection_closed`: The sender closed the connection before the upload finished.\n- `server_error`: An unexpected error while handling the request.\n- `spool_full_disk_gate`: The server paused intake to protect its disk from filling.\n- `spool_full_storage_write`: A buffer write failed while accepting the request.\n- `spool_full_ingest_queue`: The intake queue was momentarily full.\n- `spool_full_wal_unavailable`: The write buffer was restarting.\n- `auth_unavailable`: The ingest key could not be verified because the verification service was unreachable. The key itself was not rejected.\n\nReasons where the request itself must change. Retrying the same request is refused again:\n\n- `auth_missing_credentials`: No ingest key was provided.\n- `auth_invalid_credentials`: The ingest key is wrong or revoked.\n- `payload_too_large`: The payload exceeds the size limit.\n- `request_validation_failed`: The request body or parameters are invalid.\n- `frame_invalid`: A frame in the payload could not be parsed.\n- `empty_payload`: The request carried no data.\n- `source_deleted`: The target source no longer exists.\n",
|
|
19
|
-
"api/projects": "# Projects\n\n## Project Model\n\n### Fields\n\n- **`object`** `\"project\"`\n\n- **`id`** `string`\n\n Project identifier prefixed with `prj_`.\n\n- **`team_id`** `string`\n\n- **`team_name`** `string`\n\n- **`trial_expires_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the team's trial server-hours run out (with a card, at the current rate). The hours are\n shared across the team's projects.\n\n- **`name`** `string`\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Metrics collection begins at this time.\n\n- **`created_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`updated_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`deleted_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Scheduled deletion time; `null` when deletion is not scheduled.\n\n- **`last_activity_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Most recent authenticated ingest time; `null` if none has occurred.\n\n- **`late_data_window_minutes`** `number`\n\n How many minutes behind the completeness watermark an event with an overridden timestamp may\n arrive and still be included automatically. Later data is recorded and surfaced for manual\n re-backfill. 0 means the watermark is final as it advances. Data sent live is never affected.\n\n- **`server_endpoint`** `string | null`\n\n Project-specific ingest endpoint; `null` while unavailable.\n\n- **`queued_server_count`** `number | null`\n\n Server count a scale request asked for that is waiting to be applied, because a platform update\n is in progress or the project has not finished updating to the current platform version. `null`\n when nothing is queued.\n\n- **`storage_gb`** `number`\n\n Stored data for this project, in gigabytes of uncompressed data: raw ingested files and\n artifacts, plus view output and minute-level rollups. Recalculated hourly; `billing_updated_at`\n is the last refresh.\n\n- **`billing_period_server_months`** `number`\n\n Server-months this project's servers have accrued in the current calendar-month billing period,\n counted up to the last refresh.\n\n- **`billing_updated_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Last billing-cache refresh; `null` before the first calculation.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Late Data Model\n\n### Fields\n\n- **`object`** `\"late_data_file\"`\n\n- **`id`** `string`\n\n Unique identifier, prefixed with `ldf_`.\n\n- **`view_id`** `string`\n\n- **`view_name`** `string`\n\n Display name of the view whose data carried the late events.\n\n- **`excluded_count`** `number`\n\n How many events were kept out of charts because their timestamps fell behind the project's late\n data window. The events themselves are stored; only their aggregation waits.\n\n- **`min_event_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n The earliest event time among the excluded events. A re-backfill folds back to this instant.\n\n- **`max_event_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n The latest event time among the excluded events.\n\n- **`exclusion_below`** [`ISODateString`](/api/projects#iso-date-string)\n\n The boundary the events fell behind. Events at or after it were included normally.\n\n- **`refold_queued_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When a re-backfill was requested for these events; null until requested.\n\n- **`refolded_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the re-backfill finished folding the events into charts; null until complete.\n\n- **`created_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Live Pipeline Model\n\n### Fields\n\n- **`object`** `\"project_pipeline_live\"`\n\n- **`observed_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`pending_records`** `number | null`\n\n Valid spooled records awaiting write, including processing. Null when the queue is unknown.\n\n- **`processing_records`** `number | null`\n\n Pending records currently being processed.\n\n- **`pending_observed_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Oldest contributing queue observation, independent of the server heartbeat.\n\n- **`pending_is_estimated`** `boolean`\n\n The queue changed during inspection; available counts are estimates from durable records.\n\n- **`state`** `\"fresh\" | \"stale\" | \"unavailable\"`\n\n Queue freshness across all current project servers, including deployment surges.\n\n- **`contributing_servers`** `number`\n\n- **`fresh_servers`** `number`\n\n- **`window_start_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Inclusive start of the last completed minute.\n\n- **`window_end_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Exclusive end of the last completed minute.\n\n- **`throughput_records`** `number | null`\n\n Records processed in the completed minute. Null when any contributor lacks telemetry.\n\n- **`errors`** `number | null`\n\n Rejected requests and dropped frames in the completed minute, not a record count.\n\n- **`pipeline_error_counts`** `Partial | null`\n\n Map from each `PipelineErrorReason` key to its error count for the completed minute. Omitted\n keys had no errors; `null` means telemetry is incomplete.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### PipelineErrorReason\n\n`\"auth_missing_credentials\" | \"auth_invalid_credentials\" | \"payload_too_large\" | \"request_validation_failed\" | \"server_error\" | \"spool_full_disk_gate\" | \"spool_full_storage_write\" | \"spool_full_ingest_queue\" | \"spool_full_wal_unavailable\" | \"frame_invalid\" | \"empty_payload\" | \"source_deleted\" | \"connection_closed\" | \"auth_unavailable\"`\n\n## Usage Sample Model\n\n### Fields\n\n- **`object`** `\"usage_sample\"`\n\n- **`sampled_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n When the reading was taken. Readings are hourly, on the hour. With `interval=day` this is the\n timestamp of the day's last reading, not midnight.\n\n- **`collection_gb`** `number`\n\n Gigabytes of raw event data held in the project's collections, measured uncompressed, exactly\n as it is billed.\n\n- **`artifact_gb`** `number`\n\n Gigabytes of artifacts extracted from the project's events, measured uncompressed.\n\n- **`view_gb`** `number`\n\n Gigabytes of view records the project's views produced, measured uncompressed.\n\n- **`rollup_gb`** `number`\n\n Gigabytes of rollup data behind the project's charts, measured uncompressed. Counts the minute\n tier only, matching what invoices charge for.\n\n- **`total_gb`** `number`\n\n The four components added together: everything the project stored at this reading.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Attention Item Model\n\n### Fields\n\n- **`object`** `\"attention_item\"`\n\n- **`type`** [`AttentionItemType`](/api/projects#attention-item-type)\n\n- **`tier`** [`AttentionTier`](/api/projects#attention-tier)\n\n- **`resource_id`** `string | null`\n\n The resource to open to act on the condition: the metric behind a firing monitor, the view\n behind a failing transform, otherwise the check, view, metric, drain, pull or server itself.\n Null when the item covers the project as a whole, which is the case for refused requests.\n\n- **`resource_name`** `string | null`\n\n The name shown for the condition, which can belong to a related resource: a firing monitor's\n item names the monitor while `resource_id` opens its metric. Null whenever `resource_id` is\n null.\n\n- **`count`** `number | null`\n\n How much of the condition there is, in the unit that fits it: requests refused (not records)\n over the last 24 hours, or the last hour for capacity, series a monitor is firing on, a view's\n failing transforms, events waiting on a shape change, consecutive failures of a check, pull, or\n drain, or a hot server's average load in percent. Null when the condition has no quantity.\n\n- **`since`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the condition started, as accurately as Tailglow knows. Null when nothing on record marks\n a beginning: a check that has never once succeeded, or a server under sustained load, which is\n judged from an average rather than a start.\n\n- **`ended_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the condition stopped, for a `resolved` item: to the minute within the last hour, to the\n end of the hour before that. Null while the condition is still true, including while a server\n that was refusing has not reported since.\n\n- **`detail`** `string | null`\n\n A short machine-readable qualifier that narrows the type: the refusal reason group, the firing\n monitor's id, or `cpu` or `mem` for the load that made a server hot. A stable identifier meant\n for branching in code, never a sentence to display. Null when the type needs no qualifier.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### AttentionItemType\n\n`\"ingest_refusals\" | \"capacity_refusals\" | \"monitor_firing\" | \"check_down\" | \"transform_error\" | \"metric_error\" | \"join_error\" | \"shape_deferral\" | \"pull_suspended\" | \"drain_suspended\" | \"drain_unverified\" | \"servers_hot\"`\n\nThe condition an attention item reports. Every value is a state Tailglow entered on its own, so\nnothing a project deliberately turned off is ever reported here.\n\n#### AttentionTier\n\n`\"losing_data\" | \"firing\" | \"stalled\" | \"suspended\" | \"resolved\"`\n\nHow urgent an attention item is, most urgent first. `losing_data` means requests are being\nrefused right now in a way that loses data unless the sender acts, or were until a server that\nwas refusing stopped reporting. `firing` means something the project asked to be told about is\ncurrently true, or a server has run under sustained heavy load. `stalled` means a pipeline\nstopped making progress and existing data is going stale. `suspended` means Tailglow switched\nsomething off and it stays off until it is fixed. `resolved` means refusals that lost data have\nstopped; the item stays for a while so the loss is still visible, and says when it ended.\n\n## List Projects\n\n### Endpoint\n\nRetrieve a list of projects for the current team.\n\n```http\nGET /v1/projects\n```\n\n**Scope:** `projects:read`\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the projects. Optional. Defaults to `\"name\"`. Allowed values: `\"created_at\"`, `\"name\"`.\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: Project[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- When neither `sort` nor `order_by` is provided, the route defaults `sort` to `\"asc\"`.\n- `after` and `before` are mutually exclusive.\n\n## Retrieve Project\n\n### Endpoint\n\nRetrieve a single project.\n\n```http\nGET /v1/projects/:project_id\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nProject retrieved\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Retrieve Project Pipeline\n\n### Endpoint\n\nRetrieve ingest activity across all of a project's servers.\n\n```http\nGET /v1/projects/:project_id/pipeline\n```\n\n**Scope:** `servers:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Start time (ISO format, default: 12 hours ago). Optional.\n\n- **`end_at`** [`ISODateString`](/api/projects#iso-date-string)\n End time (ISO format, default: now). Optional.\n\n- **`interval`** `string`\n Aggregation interval. Optional. Defaults to `\"minute\"`. Allowed values: `\"minute\"`, `\"hour\"`.\n\n### Response\n\nProject pipeline retrieved\n\n```ts\n{\n message: string;\n data: TimeseriesAggregation;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Includes temporary deployment servers and their archived history. Pending averages valid queued records; throughput counts drained records. Older pending history without record counts is unknown.\n\n## Retrieve Live Project Pipeline\n\n### Endpoint\n\nRetrieve the current project queue and ingest totals for the last completed minute.\n\n```http\nGET /v1/projects/:project_id/pipeline/live\n```\n\n**Scope:** `servers:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nLive project pipeline retrieved\n\n```ts\n{\n message: string;\n data: ProjectPipelineLive;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Includes temporary deployment servers. Queue freshness is independent of heartbeat freshness. Observations taken while queues change return estimated counts from durable records; unreadable observations or unknown write outcomes return null counts.\n- Throughput and error totals cover the last completed minute. Errors count requests or frames, and totals are null when telemetry is incomplete.\n\n## Create Project\n\n### Endpoint\n\nCreate a new project for the current team.\n\n```http\nPOST /v1/projects\n```\n\n**Scope:** `projects:write`\n\n### Request Body\n\n- **`name`** `string` -- **Required**\n Display name for the project. Minimum length: `1`. Maximum length: `60`.\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Date and time when the project began collecting data. Optional.\n\n### Response\n\nYour project has been created.\n\n```ts\n{\n message: string;\n data: Project;\n status: 201;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Update Project\n\n### Endpoint\n\nUpdate an existing project.\n\n```http\nPOST /v1/projects/:project_id\n```\n\n**Scope:** `projects:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Request Body\n\n- **`name`** `string`\n Display name for the project. Optional. Minimum length: `1`. Maximum length: `60`.\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Date and time when the project began collecting data. Optional.\n\n- **`late_data_window_minutes`** `integer`\n How many minutes behind the completeness watermark an event with an overridden timestamp may arrive and still be included automatically. Later data is recorded and surfaced for manual re-backfill instead of being included. 0 means the watermark is final as it advances. Only events with overridden timestamps can be late; data sent live is never affected. Maximum 129600 (90 days). Optional. Minimum: `0`. Maximum: `129600`.\n\n- **`deleted_at`** `null`\n Set to null to cancel a scheduled project deletion. Optional.\n\n### Response\n\nYour project has been updated.\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Delete Project\n\n### Endpoint\n\nSchedule a project for deletion.\n\n```http\nDELETE /v1/projects/:project_id\n```\n\n**Scope:** `projects:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The project is hidden immediately and permanently removed 7 days later. Restore it before then by updating it with `deleted_at` set to null.\n\n## Force Delete Project\n\n### Endpoint\n\nDelete a project permanently, without waiting out its restore window.\n\n```http\nDELETE /v1/projects/:project_id/force\n```\n\n**Scope:** `projects:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nProject queued for permanent deletion.\n\n```ts\n{\n message: string;\n data: null;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Works on a live project as well as one already scheduled for deletion.\n- Every source, collection, view, metric and record in the project is destroyed immediately, and its servers are torn down. Nothing here can be restored.\n\n## List Late Data\n\n### Endpoint\n\nRetrieve the events held out of charts by the project's late data window, grouped per data file.\n\n```http\nGET /v1/projects/:project_id/late_data\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the late data records. Optional. Defaults to `\"created_at\"`. Allowed values: `\"created_at\"`, `\"min_event_at\"`.\n\n- **`refolded`** `string`\n Filter by re-backfill state: false returns records whose events are still excluded from charts, true returns records a completed re-backfill has folded in. Optional. Allowed values: `\"true\"`, `\"false\"`.\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: LateDataFile[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Events with overridden timestamps beyond the late data window are stored and counted here instead of entering charts. Data sent live is never held.\n- Records with `refolded_at` set have already been folded into charts by a completed re-backfill; filter with `refolded=false` for records still waiting.\n- `after` and `before` are mutually exclusive.\n\n## Re-backfill Late Data\n\n### Endpoint\n\nStart a re-backfill that folds one late data record's events into charts.\n\n```http\nPOST /v1/projects/:project_id/late_data/:late_data_file_id/re_backfill\n```\n\n**Scope:** `projects:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`late_data_file_id`** `string` -- **Required**\n Unique identifier of the late data.\n\n### Response\n\nRe-backfill queued. The events will appear in charts as the fold completes.\n\n```ts\n{\n message: string;\n data: LateDataFile;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Idempotent: requesting a re-backfill that is already queued or complete returns the record unchanged.\n- The fold is bounded to the excluded events, so data already in charts is never counted twice. `refolded_at` is set once the fold's durable receipts land.\n\n## Retrieve Project Usage\n\n### Endpoint\n\nRetrieve how much the project stored over a time range.\n\n```http\nGET /v1/projects/:project_id/usage\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string) -- **Required**\n Start of the range, inclusive (ISO format).\n\n- **`end_at`** [`ISODateString`](/api/projects#iso-date-string)\n End of the range, inclusive (ISO format, default: now). Optional.\n\n- **`interval`** `string`\n Reading cadence returned: every hourly reading, or one reading per UTC day. Optional. Defaults to `\"hour\"`. Allowed values: `\"hour\"`, `\"day\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: UsageSample[];\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Readings are taken hourly and are the same measurements the project is billed on. Gigabytes are logical (uncompressed) bytes.\n- `interval=day` returns the last reading of each UTC day rather than an average, so a row is what the project held when the day closed. Its `sampled_at` is that reading's own hour.\n- Readings start when Tailglow began recording them, so a range reaching further back returns nothing for the hours before that.\n- `start_at` must be earlier than `end_at`, and the range cannot be longer than 400 days.\n\n## Retrieve Project Attention\n\n### Endpoint\n\nRetrieve everything in the project that is asking for a human right now.\n\n```http\nGET /v1/projects/:project_id/attention\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\n```ts\n{\n message: string;\n data: AttentionItem[];\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- An item appears only when Tailglow entered a state on its own. Anything a project chose, such as a paused pull, a paused drain, or a paused monitor, is never reported here.\n- `tier` orders the list. `losing_data` means requests are being refused right now, within the last 5 minutes: for a reason a retry cannot fix, or for capacity after at least 5 minutes of unbroken refusals. `firing` means a monitor or check the project set up is currently triggered, or a server has run under sustained heavy load. `stalled` means a pipeline stopped making progress and its data is going stale. `suspended` means Tailglow switched something off and it stays off until it is fixed. `resolved` means refusals that lost data have stopped; `ended_at` says when.\n- Items disappear the moment their condition clears, with one exception so a loss is not missed: refusals that stop stay as `resolved`, for up to 24 hours for a key or payload refusal and up to an hour for capacity. A refusal item's `count` covers that whole window, not only the current spell. Refusals only count as stopped once every running server that was refusing has reported since; until then the item stays `losing_data`. Readings from the project's servers are cached briefly, so a condition that just started can take up to a minute to appear.\n- Items cover only resources the caller's key or role can read: without a resource's read permission, its conditions are left out. Refusal and server load items need `servers:read`, and firing monitors need `alerts:read`.\n- Items are already ranked, most urgent first. One item covers each firing monitor, and each view's failing transforms, joins, or shape waits. The response is capped per condition so a project in a bad state returns a readable list rather than every affected resource.\n\n",
|
|
19
|
+
"api/projects": "# Projects\n\n## Project Model\n\n### Fields\n\n- **`object`** `\"project\"`\n\n- **`id`** `string`\n\n Project identifier prefixed with `prj_`.\n\n- **`team_id`** `string`\n\n- **`team_name`** `string`\n\n- **`trial_expires_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the team's trial server-hours run out (with a card, at the current rate). The hours are\n shared across the team's projects.\n\n- **`name`** `string`\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Metrics collection begins at this time.\n\n- **`created_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`updated_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`deleted_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Scheduled deletion time; `null` when deletion is not scheduled.\n\n- **`last_activity_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Most recent authenticated ingest time; `null` if none has occurred.\n\n- **`late_data_window_minutes`** `number`\n\n How many minutes behind the completeness watermark an event with an overridden timestamp may\n arrive and still be included automatically. Later data is recorded and surfaced for manual\n re-backfill. 0 means the watermark is final as it advances. Data sent live is never affected.\n\n- **`server_endpoint`** `string | null`\n\n Project-specific ingest endpoint; `null` while unavailable.\n\n- **`queued_server_count`** `number | null`\n\n Server count a scale request asked for that is waiting to be applied, because a platform update\n is in progress or the project has not finished updating to the current platform version. `null`\n when nothing is queued.\n\n- **`storage_gb`** `number`\n\n Stored data for this project, in gigabytes of uncompressed data: raw ingested files and\n artifacts, plus view output and minute-level rollups. Recalculated hourly; `billing_updated_at`\n is the last refresh.\n\n- **`billing_period_server_months`** `number`\n\n Server-months this project's servers have accrued in the current calendar-month billing period,\n counted up to the latest hourly billing pass. Every pass recounts it, including an hour that\n keeps the previous `storage_gb`.\n\n- **`billing_updated_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When `storage_gb` was last recalculated; `null` before the first calculation. An hour whose\n recalculation could not read the project's data keeps the previous size and this time.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Late Data Model\n\n### Fields\n\n- **`object`** `\"late_data_file\"`\n\n- **`id`** `string`\n\n Unique identifier, prefixed with `ldf_`.\n\n- **`view_id`** `string`\n\n- **`view_name`** `string`\n\n Display name of the view whose data carried the late events.\n\n- **`excluded_count`** `number`\n\n How many events were kept out of charts because their timestamps fell behind the project's late\n data window. The events themselves are stored; only their aggregation waits.\n\n- **`min_event_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n The earliest event time among the excluded events. A re-backfill folds back to this instant.\n\n- **`max_event_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n The latest event time among the excluded events.\n\n- **`exclusion_below`** [`ISODateString`](/api/projects#iso-date-string)\n\n The boundary the events fell behind. Events at or after it were included normally.\n\n- **`refold_queued_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When a re-backfill was requested for these events; null until requested.\n\n- **`refolded_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the re-backfill finished folding the events into charts; null until complete.\n\n- **`created_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Live Pipeline Model\n\n### Fields\n\n- **`object`** `\"project_pipeline_live\"`\n\n- **`observed_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n- **`pending_records`** `number | null`\n\n Valid spooled records awaiting write, including processing. Null when the queue is unknown.\n\n- **`processing_records`** `number | null`\n\n Pending records currently being processed.\n\n- **`pending_observed_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n Oldest contributing queue observation, independent of the server heartbeat.\n\n- **`pending_is_estimated`** `boolean`\n\n The queue changed during inspection; available counts are estimates from durable records.\n\n- **`state`** `\"fresh\" | \"stale\" | \"unavailable\"`\n\n Queue freshness across all current project servers, including deployment surges.\n\n- **`contributing_servers`** `number`\n\n- **`fresh_servers`** `number`\n\n- **`window_start_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Inclusive start of the last completed minute.\n\n- **`window_end_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n Exclusive end of the last completed minute.\n\n- **`throughput_records`** `number | null`\n\n Records processed in the completed minute. Null when any contributor lacks telemetry.\n\n- **`errors`** `number | null`\n\n Rejected requests and dropped frames in the completed minute, not a record count.\n\n- **`pipeline_error_counts`** `Partial | null`\n\n Map from each `PipelineErrorReason` key to its error count for the completed minute. Omitted\n keys had no errors; `null` means telemetry is incomplete.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### PipelineErrorReason\n\n`\"auth_missing_credentials\" | \"auth_invalid_credentials\" | \"payload_too_large\" | \"request_validation_failed\" | \"server_error\" | \"spool_full_disk_gate\" | \"spool_full_storage_write\" | \"spool_full_ingest_queue\" | \"spool_full_wal_unavailable\" | \"frame_invalid\" | \"empty_payload\" | \"source_deleted\" | \"connection_closed\" | \"auth_unavailable\"`\n\n## Usage Sample Model\n\n### Fields\n\n- **`object`** `\"usage_sample\"`\n\n- **`sampled_at`** [`ISODateString`](/api/projects#iso-date-string)\n\n When the reading was taken. Readings are hourly, on the hour. With `interval=day` this is the\n timestamp of the day's last reading, not midnight.\n\n- **`collection_gb`** `number`\n\n Gigabytes of raw event data held in the project's collections, measured uncompressed, exactly\n as it is billed.\n\n- **`artifact_gb`** `number`\n\n Gigabytes of artifacts extracted from the project's events, measured uncompressed.\n\n- **`view_gb`** `number`\n\n Gigabytes of view records the project's views produced, measured uncompressed.\n\n- **`rollup_gb`** `number`\n\n Gigabytes of rollup data behind the project's charts, measured uncompressed. Counts the minute\n tier only, matching what invoices charge for.\n\n- **`total_gb`** `number`\n\n The four components added together: everything the project stored at this reading.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Attention Item Model\n\n### Fields\n\n- **`object`** `\"attention_item\"`\n\n- **`type`** [`AttentionItemType`](/api/projects#attention-item-type)\n\n- **`tier`** [`AttentionTier`](/api/projects#attention-tier)\n\n- **`resource_id`** `string | null`\n\n The resource to open to act on the condition: the metric behind a firing monitor, the view\n behind a failing transform, otherwise the check, view, metric, drain, pull or server itself.\n Null when the item covers the project as a whole, which is the case for refused requests.\n\n- **`resource_name`** `string | null`\n\n The name shown for the condition, which can belong to a related resource: a firing monitor's\n item names the monitor while `resource_id` opens its metric. Null whenever `resource_id` is\n null.\n\n- **`count`** `number | null`\n\n How much of the condition there is, in the unit that fits it: requests refused (not records)\n over the last 24 hours, or the last hour for capacity, series a monitor is firing on, a view's\n failing transforms, events waiting on a shape change, consecutive failures of a check, pull, or\n drain, or a hot server's average load in percent. Null when the condition has no quantity.\n\n- **`since`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the condition started, as accurately as Tailglow knows. Null when nothing on record marks\n a beginning: a check that has never once succeeded, or a server under sustained load, which is\n judged from an average rather than a start.\n\n- **`ended_at`** [`ISODateString | null`](/api/projects#iso-date-string)\n\n When the condition stopped, for a `resolved` item: to the minute within the last hour, to the\n end of the hour before that. Null while the condition is still true, including while a server\n that was refusing has not reported since.\n\n- **`detail`** `string | null`\n\n A short machine-readable qualifier that narrows the type: the refusal reason group, the firing\n monitor's id, or `cpu` or `mem` for the load that made a server hot. A stable identifier meant\n for branching in code, never a sentence to display. Null when the type needs no qualifier.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### AttentionItemType\n\n`\"ingest_refusals\" | \"capacity_refusals\" | \"monitor_firing\" | \"check_down\" | \"transform_error\" | \"metric_error\" | \"join_error\" | \"shape_deferral\" | \"pull_suspended\" | \"drain_suspended\" | \"drain_unverified\" | \"servers_hot\"`\n\nThe condition an attention item reports. Every value is a state Tailglow entered on its own, so\nnothing a project deliberately turned off is ever reported here.\n\n#### AttentionTier\n\n`\"losing_data\" | \"firing\" | \"stalled\" | \"suspended\" | \"resolved\"`\n\nHow urgent an attention item is, most urgent first. `losing_data` means requests are being\nrefused right now in a way that loses data unless the sender acts, or were until a server that\nwas refusing stopped reporting. `firing` means something the project asked to be told about is\ncurrently true, or a server has run under sustained heavy load. `stalled` means a pipeline\nstopped making progress and existing data is going stale. `suspended` means Tailglow switched\nsomething off and it stays off until it is fixed. `resolved` means refusals that lost data have\nstopped; the item stays for a while so the loss is still visible, and says when it ended.\n\n## List Projects\n\n### Endpoint\n\nRetrieve a list of projects for the current team.\n\n```http\nGET /v1/projects\n```\n\n**Scope:** `projects:read`\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the projects. Optional. Defaults to `\"name\"`. Allowed values: `\"created_at\"`, `\"name\"`.\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: Project[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- When neither `sort` nor `order_by` is provided, the route defaults `sort` to `\"asc\"`.\n- `after` and `before` are mutually exclusive.\n\n## Retrieve Project\n\n### Endpoint\n\nRetrieve a single project.\n\n```http\nGET /v1/projects/:project_id\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nProject retrieved\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Retrieve Project Pipeline\n\n### Endpoint\n\nRetrieve ingest activity across all of a project's servers.\n\n```http\nGET /v1/projects/:project_id/pipeline\n```\n\n**Scope:** `servers:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Start time (ISO format, default: 12 hours ago). Optional.\n\n- **`end_at`** [`ISODateString`](/api/projects#iso-date-string)\n End time (ISO format, default: now). Optional.\n\n- **`interval`** `string`\n Aggregation interval. Optional. Defaults to `\"minute\"`. Allowed values: `\"minute\"`, `\"hour\"`.\n\n### Response\n\nProject pipeline retrieved\n\n```ts\n{\n message: string;\n data: TimeseriesAggregation;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Includes temporary deployment servers and their archived history. Pending averages valid queued records; throughput counts drained records. Older pending history without record counts is unknown.\n\n## Retrieve Live Project Pipeline\n\n### Endpoint\n\nRetrieve the current project queue and ingest totals for the last completed minute.\n\n```http\nGET /v1/projects/:project_id/pipeline/live\n```\n\n**Scope:** `servers:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nLive project pipeline retrieved\n\n```ts\n{\n message: string;\n data: ProjectPipelineLive;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Includes temporary deployment servers. Queue freshness is independent of heartbeat freshness. Observations taken while queues change return estimated counts from durable records; unreadable observations or unknown write outcomes return null counts.\n- Throughput and error totals cover the last completed minute. Errors count requests or frames, and totals are null when telemetry is incomplete.\n\n## Create Project\n\n### Endpoint\n\nCreate a new project for the current team.\n\n```http\nPOST /v1/projects\n```\n\n**Scope:** `projects:write`\n\n### Request Body\n\n- **`name`** `string` -- **Required**\n Display name for the project. Minimum length: `1`. Maximum length: `60`.\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Date and time when the project began collecting data. Optional.\n\n### Response\n\nYour project has been created.\n\n```ts\n{\n message: string;\n data: Project;\n status: 201;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Update Project\n\n### Endpoint\n\nUpdate an existing project.\n\n```http\nPOST /v1/projects/:project_id\n```\n\n**Scope:** `projects:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Request Body\n\n- **`name`** `string`\n Display name for the project. Optional. Minimum length: `1`. Maximum length: `60`.\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string)\n Date and time when the project began collecting data. Optional.\n\n- **`late_data_window_minutes`** `integer`\n How many minutes behind the completeness watermark an event with an overridden timestamp may arrive and still be included automatically. Later data is recorded and surfaced for manual re-backfill instead of being included. 0 means the watermark is final as it advances. Only events with overridden timestamps can be late; data sent live is never affected. Maximum 129600 (90 days). Optional. Minimum: `0`. Maximum: `129600`.\n\n- **`deleted_at`** `null`\n Set to null to cancel a scheduled project deletion. Optional.\n\n### Response\n\nYour project has been updated.\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Delete Project\n\n### Endpoint\n\nSchedule a project for deletion.\n\n```http\nDELETE /v1/projects/:project_id\n```\n\n**Scope:** `projects:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\n```ts\n{\n message: string;\n data: Project;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The project is hidden immediately and permanently removed 7 days later. Restore it before then by updating it with `deleted_at` set to null.\n\n## Force Delete Project\n\n### Endpoint\n\nDelete a project permanently, without waiting out its restore window.\n\n```http\nDELETE /v1/projects/:project_id/force\n```\n\n**Scope:** `projects:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\nProject queued for permanent deletion.\n\n```ts\n{\n message: string;\n data: null;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Works on a live project as well as one already scheduled for deletion.\n- Every source, collection, view, metric and record in the project is destroyed immediately, and its servers are torn down. Nothing here can be restored.\n\n## List Late Data\n\n### Endpoint\n\nRetrieve the events held out of charts by the project's late data window, grouped per data file.\n\n```http\nGET /v1/projects/:project_id/late_data\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the late data records. Optional. Defaults to `\"created_at\"`. Allowed values: `\"created_at\"`, `\"min_event_at\"`.\n\n- **`refolded`** `string`\n Filter by re-backfill state: false returns records whose events are still excluded from charts, true returns records a completed re-backfill has folded in. Optional. Allowed values: `\"true\"`, `\"false\"`.\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: LateDataFile[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Events with overridden timestamps beyond the late data window are stored and counted here instead of entering charts. Data sent live is never held.\n- Records with `refolded_at` set have already been folded into charts by a completed re-backfill; filter with `refolded=false` for records still waiting.\n- `after` and `before` are mutually exclusive.\n\n## Re-backfill Late Data\n\n### Endpoint\n\nStart a re-backfill that folds one late data record's events into charts.\n\n```http\nPOST /v1/projects/:project_id/late_data/:late_data_file_id/re_backfill\n```\n\n**Scope:** `projects:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`late_data_file_id`** `string` -- **Required**\n Unique identifier of the late data.\n\n### Response\n\nRe-backfill queued. The events will appear in charts as the fold completes.\n\n```ts\n{\n message: string;\n data: LateDataFile;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Idempotent: requesting a re-backfill that is already queued or complete returns the record unchanged.\n- The fold is bounded to the excluded events, so data already in charts is never counted twice. `refolded_at` is set once the fold's durable receipts land.\n\n## Retrieve Project Usage\n\n### Endpoint\n\nRetrieve how much the project stored over a time range.\n\n```http\nGET /v1/projects/:project_id/usage\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`start_at`** [`ISODateString`](/api/projects#iso-date-string) -- **Required**\n Start of the range, inclusive (ISO format).\n\n- **`end_at`** [`ISODateString`](/api/projects#iso-date-string)\n End of the range, inclusive (ISO format, default: now). Optional.\n\n- **`interval`** `string`\n Reading cadence returned: every hourly reading, or one reading per UTC day. Optional. Defaults to `\"hour\"`. Allowed values: `\"hour\"`, `\"day\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: UsageSample[];\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Readings are taken hourly and are the same measurements the project is billed on. Gigabytes are logical (uncompressed) bytes.\n- `interval=day` returns the last reading of each UTC day rather than an average, so a row is what the project held when the day closed. Its `sampled_at` is that reading's own hour.\n- Readings start when Tailglow began recording them, so a range reaching further back returns nothing for the hours before that.\n- `start_at` must be earlier than `end_at`, and the range cannot be longer than 400 days.\n\n## Retrieve Project Attention\n\n### Endpoint\n\nRetrieve everything in the project that is asking for a human right now.\n\n```http\nGET /v1/projects/:project_id/attention\n```\n\n**Scope:** `projects:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Response\n\n```ts\n{\n message: string;\n data: AttentionItem[];\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- An item appears only when Tailglow entered a state on its own. Anything a project chose, such as a paused pull, a paused drain, or a paused monitor, is never reported here.\n- `tier` orders the list. `losing_data` means requests are being refused right now, within the last 5 minutes: for a reason a retry cannot fix, or for capacity after at least 5 minutes of unbroken refusals. `firing` means a monitor or check the project set up is currently triggered, or a server has run under sustained heavy load. `stalled` means a pipeline stopped making progress and its data is going stale. `suspended` means Tailglow switched something off and it stays off until it is fixed. `resolved` means refusals that lost data have stopped; `ended_at` says when.\n- Items disappear the moment their condition clears, with one exception so a loss is not missed: refusals that stop stay as `resolved`, for up to 24 hours for a key or payload refusal and up to an hour for capacity. A refusal item's `count` covers that whole window, not only the current spell. Refusals only count as stopped once every running server that was refusing has reported since; until then the item stays `losing_data`. Readings from the project's servers are cached briefly, so a condition that just started can take up to a minute to appear.\n- Items cover only resources the caller's key or role can read: without a resource's read permission, its conditions are left out. Refusal and server load items need `servers:read`, and firing monitors need `alerts:read`.\n- Items are already ranked, most urgent first. One item covers each firing monitor, and each view's failing transforms, joins, or shape waits. The response is capped per condition so a project in a bad state returns a readable list rather than every affected resource.\n\n",
|
|
20
20
|
"api/sources": "# Sources\n\n## Source Model\n\n### Fields\n\n- **`object`** `\"source\"`\n\n- **`id`** `string`\n\n Unique identifier, prefixed with `src_`.\n\n- **`project_id`** `string`\n\n- **`project_name`** `string`\n\n- **`name`** `string`\n\n Unique within its project.\n\n- **`storage_gb`** `number`\n\n Data this source has ingested, in gigabytes of uncompressed data: collection files plus\n uploaded artifacts. Recalculated hourly.\n\n- **`schema_count`** `number`\n\n How many schema versions this source has produced.\n\n- **`collections_count`** `number`\n\n How many collections this source feeds.\n\n- **`deleted_at`** [`ISODateString | null`](/api/sources#iso-date-string)\n\n When the source is scheduled to be deleted; null when it is not.\n\n- **`created_at`** [`ISODateString`](/api/sources#iso-date-string)\n\n- **`updated_at`** [`ISODateString`](/api/sources#iso-date-string)\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## List Sources\n\n### Endpoint\n\nRetrieve a list of sources for a project.\n\n```http\nGET /v1/projects/:project_id/sources\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the sources. Optional. Defaults to `\"name\"`. Allowed values: `\"created_at\"`, `\"name\"`, `\"updated_at\"`.\n\n- **`project_id`** `string`\n Filter to sources belonging to a single project. Optional.\n\n- **`deleted_at`** [`NullableDateFilter`](/api/sources#nullable-date-filter)\n Filter by scheduled deletion date. Use `null` for sources that are not scheduled for deletion, `not:null` for sources that are. Optional.\n\n- **`limit`** `number`\n Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Optional. Defaults to `\"asc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: Source[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `after` and `before` are mutually exclusive.\n\n## Retrieve Source\n\n### Endpoint\n\nRetrieve a single source.\n\n```http\nGET /v1/projects/:project_id/sources/:source_id\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Response\n\nSource retrieved\n\n```ts\n{\n message: string;\n data: Source;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Create Source\n\n### Endpoint\n\nCreate a source in a project.\n\n```http\nPOST /v1/projects/:project_id/sources\n```\n\n**Scope:** `sources:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Request Body\n\n- **`name`** `string` -- **Required**\n Display name for the source. Minimum length: `1`. Maximum length: `128`.\n\n- **`project_id`** `string`\n Project the source belongs to. Ignored when the nested path supplies it. Optional.\n\n### Response\n\nSource created\n\n```ts\n{\n message: string;\n data: Source;\n status: 201;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The project is supplied by the path.\n- Source names are unique within a project.\n\n## Update Source\n\n### Endpoint\n\nUpdate a source.\n\n```http\nPOST /v1/projects/:project_id/sources/:source_id\n```\n\n**Scope:** `sources:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Request Body\n\n- **`name`** `string`\n Display name for the source. Optional. Minimum length: `1`. Maximum length: `128`.\n\n- **`deleted_at`** `null`\n Send `null` to restore a source that is scheduled for deletion. The deletion date itself is set by the delete endpoint and cannot be written here. Optional.\n\n### Response\n\nSource updated\n\n```ts\n{\n message: string;\n data: Source;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Send `deleted_at` as `null` to restore a source that is scheduled for deletion.\n\n## Delete Source\n\n### Endpoint\n\nSchedule a source for deletion.\n\n```http\nDELETE /v1/projects/:project_id/sources/:source_id\n```\n\n**Scope:** `sources:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Response\n\n```ts\n{\n message: string;\n data: Source;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The source is hidden immediately and permanently removed 7 days later. Restore it before then by updating it with `deleted_at` set to null.\n\n## Force Delete Source\n\n### Endpoint\n\nDelete a source permanently, without waiting out its restore window.\n\n```http\nDELETE /v1/projects/:project_id/sources/:source_id/force\n```\n\n**Scope:** `sources:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Response\n\nSource queued for permanent deletion.\n\n```ts\n{\n message: string;\n data: null;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Works on a live source as well as one already scheduled for deletion.\n- Every collection, record and file under the source is destroyed immediately. Nothing here can be restored.\n\n",
|
|
21
21
|
"api/ingest_keys": "# Ingest Keys\n\n## Ingest Key Model\n\n### Fields\n\n- **`object`** `\"ingest_key\"`\n\n- **`id`** `string`\n\n Unique identifier, prefixed with `ik_`.\n\n- **`source_id`** `string`\n\n The source this key writes into.\n\n- **`source_name`** `string | null`\n\n- **`url`** `string | null`\n\n The Tailglow-issued address to send records to, ready to use. POST your payload to it and\n append `&collection=<name>` to choose where the records land; a collection is created the first\n time data arrives for it. Lasts as long as the project does. Null until the project has a\n provisioned server, which is the only window in which no address reaches it.\n\n- **`custom_urls`** `string[]`\n\n The same source reached through the team's verified custom ingest domains, one entry each,\n every one carrying the key exactly as `url` does. Empty when none are configured. Prefer these\n for browser traffic, where a first-party host survives the blockers that reject a shared\n analytics domain. An entry disappears if its domain is removed or stops resolving.\n\n- **`key`** `string`\n\n The credential embedded in `url`. Publishable, in the sense that it belongs in client-side code\n the way an analytics site tag does. It permits writing records into this source and nothing\n else: it cannot read, and it carries no access to anything outside this source.\n\n- **`status`** [`IngestKeyStatus`](/api/ingest_keys#ingest-key-status)\n\n Whether records sent to this URL are still accepted.\n\n- **`created_at`** [`ISODateString`](/api/ingest_keys#iso-date-string)\n\n- **`last_used_at`** [`ISODateString | null`](/api/ingest_keys#iso-date-string)\n\n When data was last received at this URL; null if it has never been used.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### IngestKeyStatus\n\n`\"active\" | \"revoked\" | \"disabled\"`\n\n## List Ingest Keys\n\n### Endpoint\n\nRetrieve every address that can send records to a source.\n\n```http\nGET /v1/projects/:project_id/sources/:source_id/ingest_keys\n```\n\n**Scope:** `ingest_keys:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the ingest keys. Optional. Defaults to `\"created_at\"`. Allowed values: `\"created_at\"`, `\"status\"`.\n\n- **`status`** [`IngestKeyStatus`](/api/ingest_keys#ingest-key-status)\n Filter by whether the URL still accepts records. Optional.\n\n- **`project_id`** `string`\n Filter to URLs whose source belongs to a project. Optional.\n\n- **`source_id`** `string`\n Filter to URLs belonging to a single source. Optional.\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: IngestKey[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `after` and `before` are mutually exclusive.\n\n## Retrieve Ingest Key\n\n### Endpoint\n\nRetrieve a single ingest key.\n\n```http\nGET /v1/projects/:project_id/sources/:source_id/ingest_keys/:ingest_key_id\n```\n\n**Scope:** `ingest_keys:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n- **`ingest_key_id`** `string` -- **Required**\n Unique identifier of the ingest key.\n\n### Response\n\nIngest key retrieved\n\n```ts\n{\n message: string;\n data: IngestKey;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Create Ingest Key\n\n### Endpoint\n\nCreate an ingest key for a source. Use this to rotate: create the replacement, deploy it, then delete the old one.\n\n```http\nPOST /v1/projects/:project_id/sources/:source_id/ingest_keys\n```\n\n**Scope:** `ingest_keys:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n### Request Body\n\n- **`source_id`** `string`\n Source the URL writes into. Ignored when the nested path supplies it. Optional.\n\n### Response\n\nIngest key created.\n\n```ts\n{\n message: string;\n data: IngestKey;\n status: 201;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The source is supplied by the path.\n- The source has to belong to your team.\n- The full `key` is returned on create and never again. Store it when you receive it.\n\n## Delete Ingest Key\n\n### Endpoint\n\nDelete an ingest key. Records already sent to it are unaffected; the address stops being accepted.\n\n```http\nDELETE /v1/projects/:project_id/sources/:source_id/ingest_keys/:ingest_key_id\n```\n\n**Scope:** `ingest_keys:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`source_id`** `string` -- **Required**\n Unique identifier of the source.\n\n- **`ingest_key_id`** `string` -- **Required**\n Unique identifier of the ingest key.\n\n### Response\n\nIngest key deleted\n\n```ts\n{\n message: string;\n data: null;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Deletion is immediate. Anything still sending with this key starts failing straight away.\n\n",
|
|
22
22
|
"api/collections": "# Collections\n\n## Collection Model\n\n### Fields\n\n- **`object`** `\"collection\"`\n\n- **`id`** `string`\n\n Unique identifier, prefixed with `col_`.\n\n- **`source_id`** `string`\n\n- **`source_name`** `string | null`\n\n- **`project_id`** `string`\n\n- **`slug`** `string`\n\n Permanent identifier used in endpoints. Cannot be changed after creation.\n\n- **`name`** `string`\n\n- **`storage_gb`** `number`\n\n Data stored in this collection's files, in gigabytes of uncompressed data. Recalculated hourly.\n\n- **`schema_count`** `number`\n\n How many schema versions this collection has, in every state.\n\n- **`views_count`** `number`\n\n How many views read from this collection.\n\n- **`drains_count`** `number`\n\n How many drains export from this collection.\n\n- **`schema_opaque_paths`** `string[][]`\n\n Object paths whose contents do not take part in schema identity, one key segment per entry.\n Records that differ only inside an opaque path share one schema version. Changing this re-keys\n the collection.\n\n- **`schema_tracked_paths`** `string[][]`\n\n Children of opaque paths that stay part of schema identity. Changing this re-keys the\n collection.\n\n- **`schema_max_depth`** `number`\n\n How many levels of nesting take part in schema identity. Changing this re-keys the collection.\n\n- **`schema_nulls`** [`SchemaRuleMode`](/api/collections#schema-rule-mode)\n\n `auto` accepts null and absent values where a mapping reads; `manual` waits for a person per\n view.\n\n- **`schema_optional_keys`** [`SchemaRuleMode`](/api/collections#schema-rule-mode)\n\n `auto` lets a record with a subset of a version's keys join it; `manual` treats absence as a\n new shape.\n\n- **`schema_detector`** [`SchemaRuleMode`](/api/collections#schema-rule-mode)\n\n `auto` applies a safe opaque-path proposal on its own; `manual` holds every proposal for a\n person.\n\n- **`schema_recurrence_gap_ms`** `number`\n\n How long after first sight a shape must recur before its version settles, in milliseconds.\n\n- **`schema_bulk_rows`** `number`\n\n A single batch carrying this many rows of a shape settles its version at once; `0` disables it.\n\n- **`schema_stale_after_ms`** `number`\n\n How long a candidate version waits to recur before it goes stale, in milliseconds.\n\n- **`schema_identity_limit`** `number`\n\n How many settled versions the collection may hold; past it, new shapes stay unclassified.\n\n- **`schema_candidate_pool`** `number`\n\n How many candidate and stale versions the collection may hold; past it, new shapes stay\n unclassified.\n\n- **`schema_alias_pool`** `number`\n\n How many exact signature hashes the collection caches for lookup.\n\n- **`schema_writer_limit`** `number`\n\n How many collection files one ingest batch may open for this collection. Shapes past the\n candidate pool get the same number of files per batch, the shapes with the most rows first; the\n rows of shapes past that budget stay unclassified and cannot be linked to a version later.\n\n- **`schema_unclassified_retention_days`** `number | null`\n\n How many days rows without a settled version are kept; null keeps them forever.\n\n- **`deleted_at`** [`ISODateString | null`](/api/collections#iso-date-string)\n\n When the collection is scheduled to be deleted; null when it is not.\n\n- **`created_at`** [`ISODateString`](/api/collections#iso-date-string)\n\n- **`updated_at`** [`ISODateString`](/api/collections#iso-date-string)\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n#### SchemaRuleMode\n\n`\"auto\" | \"manual\"`\n\n## Collection Schema Report\n\n### Fields\n\n- **`object`** `\"collection_schema_report\"`\n\n- **`collection_id`** `string`\n\n- **`rules`** `{ opaque_paths: string[][]; tracked_paths: string[][]; max_depth: number; }`\n\n The rules the report reads the collection's shapes under: the collection's own for the\n retrieve, the rules sent for a preview.\n\n- **`shapes`** `{ before: number; after: number; }`\n\n How many shapes the collection holds under its current rules (`before`) and under the report's\n rules (`after`). Equal unless the report previews a rule change; the difference is what a\n re-key would merge.\n\n- **`proposals`** [`CollectionSchemaProposal[]`](/api/collections#schema-proposal)\n\n Where the detector sees keys being invented, with what applying each proposal would do.\n\n- **`keys_look_like_data`** `boolean`\n\n Whether every shape's top-level keys are its own, such as records keyed by a date. Those keys\n are values, and no opaque path can bring the shapes together.\n\n- **`unclassified`** `{ shapes: number; rows: number; }`\n\n Shapes past the collection's pools, stored with their signature but no version, and the rows\n they carry. Nothing reads them until the pool frees or a rule brings them under a version.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## Collection Schema Proposal\n\n### Fields\n\n- **`object`** `\"collection_schema_proposal\"`\n\n- **`path`** `string[]`\n\n The path the detector proposes opaque, as key segments.\n\n- **`tracked`** `string[]`\n\n Children of the path every shape carries with one type, which stay in schema identity as\n tracked paths when the proposal is applied.\n\n- **`content_children`** `number`\n\n How many children of the path read as content: keys that keep being invented.\n\n- **`read_by_mapping`** `boolean`\n\n Whether a bound mapping reads inside the path. Applying the proposal would leave that mapping\n unverified, so the detector never applies such a proposal on its own; a person can.\n\n- **`shapes_after`** `number`\n\n How many shapes the collection would hold with this proposal applied.\n\n### Referenced Types\n\n#### ISODateString\n\n`ISODateString`\n\nAn ISO 8601 date-time string returned at the JSON API boundary.\n\n## List Collections\n\n### Endpoint\n\nRetrieve a list of collections for a project.\n\n```http\nGET /v1/projects/:project_id/collections\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Query Parameters\n\n- **`order_by`** `string`\n Field used to order the collections. Optional. Defaults to `\"name\"`. Allowed values: `\"created_at\"`, `\"name\"`, `\"updated_at\"`.\n\n- **`source_id`** `string`\n Filter to collections under a single source. Optional.\n\n- **`project_id`** `string`\n Filter to collections in a single project. Optional.\n\n- **`deleted_at`** [`NullableDateFilter`](/api/collections#nullable-date-filter)\n Filter by scheduled deletion date. Use `null` for collections that are not scheduled for deletion, `not:null` for collections that are. Optional.\n\n- **`limit`** `number`\n Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Optional. Defaults to `\"asc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: Collection[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `after` and `before` are mutually exclusive.\n\n## Retrieve Collection\n\n### Endpoint\n\nRetrieve a single collection.\n\n```http\nGET /v1/projects/:project_id/collections/:collection_id\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Response\n\nCollection retrieved\n\n```ts\n{\n message: string;\n data: Collection;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n## Create Collection\n\n### Endpoint\n\nCreate a collection under a source.\n\n```http\nPOST /v1/projects/:project_id/collections\n```\n\n**Scope:** `sources:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n### Request Body\n\n- **`name`** `string` -- **Required**\n Display name for the collection. Minimum length: `1`. Maximum length: `128`.\n\n- **`slug`** `string`\n Permanent identifier used in ingest URLs. Derived from `name` when omitted. Optional. Minimum length: `1`. Maximum length: `64`.\n\n- **`source_id`** `string` -- **Required**\n Source the collection is created under.\n\n### Response\n\nCollection created\n\n```ts\n{\n message: string;\n data: Collection;\n status: 201;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `source_id` is required.\n- `slug` is permanent. It appears in the ingest URL, so pick it deliberately.\n\n## Update Collection\n\n### Endpoint\n\nUpdate a collection.\n\n```http\nPOST /v1/projects/:project_id/collections/:collection_id\n```\n\n**Scope:** `sources:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Request Body\n\n- **`name`** `string`\n Display name for the collection. Optional. Minimum length: `1`. Maximum length: `128`.\n\n- **`expected_updated_at`** [`ISODateString`](/api/collections#iso-date-string)\n Reject this update if the collection changed since this inspected update time. Optional.\n\n- **`schema_opaque_paths`** `string[][]`\n Object paths whose contents do not take part in schema identity, each written as its key segments (`[\"metadata\", \"id\"]`). A path that names an array covers its elements and their children. Records that differ only inside an opaque path share one schema version; the raw values are still stored. Changing this re-keys the collection. Optional.\n\n- **`schema_tracked_paths`** `string[][]`\n Children of opaque paths that stay part of schema identity, written like `schema_opaque_paths`. Changing this re-keys the collection. Optional.\n\n- **`schema_max_depth`** `integer`\n How many levels of nesting take part in schema identity. Changing this re-keys the collection. Optional. Minimum: `1`. Maximum: `10`.\n\n- **`schema_nulls`** `string`\n `auto` accepts null and absent values at any path a mapping reads; `manual` waits for a person to approve each nullable input per view. Optional. Allowed values: `\"auto\"`, `\"manual\"`.\n\n- **`schema_optional_keys`** `string`\n `auto` lets a record whose keys are a subset of a version's keys join that version; `manual` treats every absent key as a different shape. Optional. Allowed values: `\"auto\"`, `\"manual\"`.\n\n- **`schema_detector`** `string`\n `auto` applies a safe opaque-path proposal from the detector on its own; `manual` holds every proposal for a person. Optional. Allowed values: `\"auto\"`, `\"manual\"`.\n\n- **`schema_recurrence_gap_ms`** `integer`\n How long after first sight a shape must be seen again before its version settles, in milliseconds. Optional. Minimum: `60000`. Maximum: `604800000`.\n\n- **`schema_bulk_rows`** `integer`\n A single batch carrying at least this many rows of a shape settles its version immediately. `0` disables the bulk path. Optional. Minimum: `0`. Maximum: `1000000`.\n\n- **`schema_stale_after_ms`** `integer`\n How long a candidate version waits to be seen again before it goes stale, in milliseconds. Optional. Minimum: `3600000`. Maximum: `7776000000`.\n\n- **`schema_identity_limit`** `integer`\n How many settled schema versions the collection may hold. Past it, new shapes stay unclassified with their signatures kept. Optional. Minimum: `1`. Maximum: `4096`.\n\n- **`schema_candidate_pool`** `integer`\n How many candidate and stale versions the collection may hold. Past it, new shapes stay unclassified. Optional. Minimum: `1`. Maximum: `8192`.\n\n- **`schema_alias_pool`** `integer`\n How many exact signature hashes the collection remembers for fast lookup. Past it, a new hash is still resolved but not cached. Optional. Minimum: `16`. Maximum: `100000`.\n\n- **`schema_writer_limit`** `integer`\n How many collection files one ingest batch may open for this collection. Shapes past the candidate pool get the same number of files per batch, the shapes with the most rows first; the rows of shapes past that budget stay unclassified and cannot be linked to a version later. Optional. Minimum: `1`. Maximum: `256`.\n\n- **`schema_unclassified_retention_days`** `integer | null`\n How many days rows without a settled schema version are kept before they are deleted. `null` keeps them forever. Optional.\n\n- **`deleted_at`** `null`\n Send `null` to restore a collection that is scheduled for deletion. The deletion date itself is set by the delete endpoint and cannot be written here. Optional.\n\n### Response\n\nCollection updated\n\n```ts\n{\n message: string;\n data: Collection;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `slug` cannot be changed after creation.\n- Send `deleted_at` as `null` to restore a collection that is scheduled for deletion.\n\n## Delete Collection\n\n### Endpoint\n\nSchedule a collection for deletion.\n\n```http\nDELETE /v1/projects/:project_id/collections/:collection_id\n```\n\n**Scope:** `sources:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Response\n\n```ts\n{\n message: string;\n data: Collection;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- The collection is hidden immediately and permanently removed 7 days later. Restore it before then by updating it with `deleted_at` set to null.\n\n## Force Delete Collection\n\n### Endpoint\n\nDelete a collection permanently, without waiting out its restore window.\n\n```http\nDELETE /v1/projects/:project_id/collections/:collection_id/force\n```\n\n**Scope:** `sources:delete`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Response\n\nCollection queued for permanent deletion.\n\n```ts\n{\n message: string;\n data: null;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Works on a live collection as well as one already scheduled for deletion.\n- Every record, schema version and file in the collection is destroyed immediately.\n\n## List Collection Schemas\n\n### Endpoint\n\nRetrieve the schema versions for a collection.\n\n```http\nGET /v1/projects/:project_id/collections/:collection_id/schemas\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Query Parameters\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n- **`state`** `string`\n Return only schema versions in this state. Optional. Allowed values: `\"candidate\"`, `\"settled\"`, `\"stale\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: CollectionSchemaVersion[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `state` is `candidate` from first sight, `settled` once the shape recurs or arrives in bulk, and `stale` when a candidate is not seen again. Only a settled version is offered to views for authoring.\n- `after` and `before` are mutually exclusive.\n\n## Update Collection Schema\n\n### Endpoint\n\nSettle a schema version by hand, so views can author against it before its shape recurs.\n\n```http\nPOST /v1/projects/:project_id/collections/:collection_id/schemas/:schema_version_id\n```\n\n**Scope:** `sources:write`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n- **`schema_version_id`** `string` -- **Required**\n Unique identifier of the schema.\n\n### Request Body\n\n- **`state`** `string` -- **Required**\n The only state a person sets. `settled` trusts the version for view authoring now, without waiting for its shape to recur; a settled version never goes back. Allowed values: `\"settled\"`.\n\n### Response\n\nSchema version settled\n\n```ts\n{\n message: string;\n data: CollectionSchemaVersion;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- `state` accepts only `settled`; a settled version never returns to candidate or stale.\n- A version that is already settled is left as it is and responds with `request_no_update`.\n\n## Retrieve Collection Schema Report\n\n### Endpoint\n\nRetrieve the detector's view of a collection: the opaque paths it proposes, whether the top-level keys are data, and how many shapes sit unclassified past the collection's pools.\n\n```http\nGET /v1/projects/:project_id/collections/:collection_id/schema_report\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Response\n\nCollection schema report retrieved\n\n```ts\n{\n message: string;\n data: CollectionSchemaReport;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- A proposal a bound mapping reads inside is reported and never applied on its own, whatever the detector switch; apply it by adding its path to the collection's `schema_opaque_paths` and its tracked children to `schema_tracked_paths`.\n- `shapes.before` and `shapes.after` are equal here; the preview is where they differ.\n\n## Preview Collection Schema Rules\n\n### Endpoint\n\nPreview a rule change: the schema report the collection would read under the rules sent, with how many shapes it holds now and how many it would hold. Nothing is changed.\n\n```http\nPOST /v1/projects/:project_id/collections/:collection_id/schema_preview\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Request Body\n\n- **`schema_opaque_paths`** `string[][]`\n Opaque paths to preview, written like the collection's `schema_opaque_paths`. Omitted, the collection's current opaque paths apply. Optional.\n\n- **`schema_tracked_paths`** `string[][]`\n Tracked paths to preview, written like the collection's `schema_tracked_paths`. Omitted, the collection's current tracked paths apply. Optional.\n\n- **`schema_max_depth`** `integer`\n Max depth to preview. Omitted, the collection's current max depth applies. Optional. Minimum: `1`. Maximum: `10`.\n\n### Response\n\nCollection schema rules previewed\n\n```ts\n{\n message: string;\n data: CollectionSchemaReport;\n status: 200;\n error: null;\n pagination: null;\n endpoint: string;\n}\n```\n\n### Comments\n\n- A rule left out of the body keeps the collection's current value.\n- `shapes.before` counts the shapes under the collection's current rules and `shapes.after` under the rules sent; the difference is what updating the collection with those rules would merge.\n\n## List Collection Documents\n\n### Endpoint\n\nRetrieve raw documents from a collection.\n\n```http\nGET /v1/projects/:project_id/collections/:collection_id/docs\n```\n\n**Scope:** `sources:read`\n\n### Path Parameters\n\n- **`project_id`** `string` -- **Required**\n Unique identifier of the project.\n\n- **`collection_id`** `string` -- **Required**\n Unique identifier of the collection.\n\n### Query Parameters\n\n- **`limit`** `number`\n Maximum number of items to return. Optional. Defaults to `25`. Minimum: `1`. Maximum: `200`.\n\n- **`after`** `string`\n Cursor from `pagination.next_cursor` of a previous response. Returns the resources after that page. Optional.\n\n- **`before`** `string`\n Cursor from `pagination.prev_cursor` of a previous response. Returns the resources before that page. Optional.\n\n- **`sort`** `string`\n Sort direction for the result set. Optional. Defaults to `\"desc\"`. Allowed values: `\"asc\"`, `\"desc\"`.\n\n### Response\n\n```ts\n{\n message: string;\n data: CollectionDoc[];\n status: 200;\n error: null;\n pagination: Pagination;\n endpoint: string;\n}\n```\n\n### Comments\n\n- Documents are returned exactly as they were sent, minus Tailglow's own reserved envelope.\n- Paging is forward-only. Pass `pagination.next_cursor` back as `after` to get the next page; no `prev_cursor` is issued, and `before` returns the first page.\n- While the project's server is stopped this answers 409 `server_stopped`. Start the server and try again.\n- `after` and `before` are mutually exclusive.\n\n",
|