# FeedSubscription

object type

Delivery is PULL ONLY v1: list runs via feedSubscriptionRuns, then mint a short-lived presigned download with mintFeedRunDownload — the BI tool authenticates as its OWN ApiKey session and there are ZERO stored credentials (the presigned ticket IS the custody; a push feed-ready event is a named growth). ⚠ THE PER-ORG WELD: organizationId names the ONE exported org (in-group live-gated); org-parented dataset rows filter to it, GROUP-parented catalog masters (Style/Product) export whole — the shared catalog IS each org's catalog. GROUP-parented (parentId === rootId); born active with nextDueAt = the birth instant (the next hourly tick runs it); at most 10 ACTIVE feeds per group (the webhook cap class); 5 consecutive FAILED RUNS fire the automatic active → suspended flip (system:repeated_delivery_failure — the exporter, never a caller); reactivate serves both inactive → active and suspended → active (fix the feed via update, then reactivate; no catch-up runs — the next run is the next cadence step). Runs prune to the newest 8 per feed (bounded custody). Owner-gated end to end (the mintApiKey posture — data-OUT is exfiltration-adjacent); NOT searchable (integration config — reached via the owner-gated list).

## Fields

| Field | Type | Notes |
| --- | --- | --- |
| `id` | [ID](/types/#scalars) `ID!` | The record’s id — a UUID the platform assigned when the record was created; every reference to this record uses it. |
| `sysId` | [String](/types/#scalars) `String!` | The group-scoped human-facing system id (FD-…). |
| `type` | [String](/types/#scalars) `String!` | The kind of record — always `FeedSubscription` here. |
| `caption` | [String](/types/#scalars) `String!` | The record’s display name — what people see it called. |
| `status` | [String](/types/#scalars) `String!` | The FSM state: active \| inactive \| suspended \| doomed. |
| `parentId` | [ID](/types/#scalars) `ID!` | The parent = the org GROUP (the org-group clause); parentId === rootId always (the WebhookSubscription class — the feed ROW is group custody; the EXPORTED SLICE is the organizationId org, the per-org law). |
| `rootId` | [ID](/types/#scalars) `ID!` | The org-group family root. |
| `createdAt` | [String](/types/#scalars) `String!` | When the record was created, as a UTC timestamp. |
| `updatedAt` | [String](/types/#scalars) `String!` | When the record last changed, as a UTC timestamp. |
| `revisionNum` | [Int](/types/#scalars) `Int!` | How many times this record has been edited; the first save is 0. |
| `revision` | [ID](/types/#scalars) `ID!` | The OCC revision token — supply it on every mutation of this record; rotates on every write. |
| `refCaptions` | [RefCaption](/types/RefCaption/) `[RefCaption!]!` | The server-composed captions of this record's declared references (the referenced-caption rule) — one row per referenced id; see RefCaption. |
| `organizationId` | [ID](/types/#scalars) `ID!` | THE PER-ORG WELD: the ONE org this feed exports — must be an in-group live Organization (gated at create AND edit); org-parented dataset rows filter to it; group-parented catalog masters export whole (the shared catalog IS each org’s catalog). |
| `dataset` | [String](/types/#scalars) `String!` | WHAT exports — one canned construct type (OrgCustomer · Style · Product · OrgVendor · Order — the two-layer law: the roster IS the vocabulary; InventoryEntry and the event-lake extracts are named growths). Mutable (routing, not authority). |
| `cadence` | [String](/types/#scalars) `String!` | HOW OFTEN — daily · weekly · monthly. nextDueAt steps by the cadence from each RUN instant (a late run does not compound); a cadence edit applies from the NEXT run (the stored due stands). |
| `format` | [String](/types/#scalars) `String!` | The file serialization — jsonl (one stored record per line, storage attrs stripped; lossless, the default posture) or csv (the flat scalar fields, header = the union; nested fields omitted — the disclosed lossy trade for flat masters). |
| `nextDueAt` | [String](/types/#scalars) `String!` | WHEN the next run is due (STORED — the hourly sweeper compares against it, never re-derives from history; birth = the create instant, so the first tick runs it). |
| `lastRunAt` | [String](/types/#scalars) | The last successful run’s instant (null until the first success). |
| `lastRunKey` | [String](/types/#scalars) | The last successful run’s object key under the group’s feeds/ prefix (the newest pull coordinate; feedSubscriptionRuns lists the retained window). |
| `consecutiveFailures` | [Int](/types/#scalars) `Int!` | Consecutive FAILED runs (the exporter’s counter — reset by the first success after failures). At 5 the automatic suspend fires. |
| `lastFailureAt` | [String](/types/#scalars) | The last failed run’s instant (failure-path-only; stands as history after recovery until the next failure overwrites). |
| `lastFailureCode` | [String](/types/#scalars) | The last failure’s short named token (rows_over_cap · serialize_fault · s3_fault); never row data. |
| `suspendedAt` | [String](/types/#scalars) | Stamped by the automatic suspend flip; cleared by reactivate. |

## Used by

- [createFeedSubscription](/reference/system-and-integration-setup/createFeedSubscription/)
- [deactivateFeedSubscription](/reference/feed-subscription/deactivateFeedSubscription/)
- [doomFeedSubscription](/reference/feed-subscription/doomFeedSubscription/)
- [feedSubscription](/reference/feed-subscription/feedSubscription/)
- [feedSubscriptions](/reference/feed-subscription/feedSubscriptions/)
- [reactivateFeedSubscription](/reference/feed-subscription/reactivateFeedSubscription/)
- [runFeedSubscriptionNow](/reference/system-and-integration-setup/runFeedSubscriptionNow/)
- [updateFeedSubscription](/reference/feed-subscription/updateFeedSubscription/)
