Pilot
Pilot automation
Native Sheets setup, scoped schedules, source and delivery status, and bounded recovery.
The controlled GA4-to-Sheets pilot is implemented and locally tested. New live scheduled delivery and controlled failure/recovery acceptance remain pending. This is not a general export service or a claim of connector or destination GA.
The gateway remains private. These are authenticated REST routes on that gateway; they do not add a public endpoint, OAuth signup flow or MCP write tool.
Routes and authorization
Section titled “Routes and authorization”| Method and path | Scope | Request body |
|---|---|---|
POST /v1/pilot/destinations | sync:write | { "destinationId": "your_destination" } |
POST /v1/pilot/schedules | sync:write | Connection, property, destination, window and cadence below |
GET /v1/pilot/schedules/{scheduleId} | query:read | None |
POST /v1/pilot/schedules/{scheduleId}/enabled | sync:write | { "enabled": true } or { "enabled": false } |
POST /v1/pilot/runs/{pipelineId}/redrive | sync:write | {} |
Bodies must be JSON, at most 4 KiB, with exactly the documented fields. The key
determines the workspace; these bodies do not accept workspaceId, a timezone,
tokens, spreadsheet IDs, arbitrary URLs or an actor identity. The private sync
Worker authenticates again, and the gateway rechecks authorization before releasing
a result or scoped error.
Background work uses the enabled schedule revision and active workspace, connection, destination and runtime grants. It does not retain the API key that configured the schedule. Revoking that key prevents further operator API calls; disable the schedule to stop its recurring work.
Set up the destination
Section titled “Set up the destination”An operator must first enroll a genuine runtime Sheets grant for the destination,
with Google’s drive.file scope. This is separate from the GA4 read-only grant.
A workbook created through another application’s connector does not establish this
application’s access. The destination setup API accepts only the enrolled
destinationId; it never receives a refresh token.
POST /v1/pilot/destinations creates the dedicated native workbook, verifies its
reserved layout and returns 200:
{ "destinationId": "your_destination", "state": "active", "spreadsheetId": "provider_assigned_id", "url": "https://docs.google.com/spreadsheets/d/provider_assigned_id/edit"}Repeating setup for an active destination verifies the same workbook and returns
the existing identity; it does not create another one. A known workbook that failed
verification can retry verification. If creation’s outcome is unknown, setup
returns 409 destination_creation_unconfirmed and leaves the destination paused for
operator review. It will not blindly issue a second create request.
Keep the reserved Daily, Provenance and hidden Ledger sheets intact. Editing their layout produces an actionable conflict. Each occurrence has its own immutable generation block; both visible views select the greatest committed generation. A delayed older delivery cannot replace a newer visible generation. Capacity is 1,000 generations per destination, with no automatic slot reuse or compaction.
Configure and enable a schedule
Section titled “Configure and enable a schedule”First complete a source sync. The service derives the property’s timezone from
existing published heads; absent timezone evidence is timezone_unverified, and
mixed published timezones are timezone_conflict.
{ "connectionId": "your_connection", "propertyId": "123456789", "destinationId": "your_destination", "windowDays": 5, "cadenceMinutes": 1440}windowDays is an integer from 1 to 31. cadenceMinutes is exactly 60 or 1440.
These are the pilot cadence options, not a billing entitlement check. The service
checks the active connection and both retained grants and returns 201:
{ "scheduleId": "generated_schedule_id", "enabled": false, "timezone": "Europe/Oslo", "windowDays": 5, "cadenceMinutes": 1440, "destinationId": "your_destination"}Retain scheduleId: every successful creation call creates a new disabled
schedule. Enabling is a separate call to its /enabled route. Only one schedule
may be enabled for a destination; another owner gives 409 schedule_conflict.
Current source/destination grants and the observed timezone are checked again.
The initial due time is assigned by the service. Cadence is elapsed time, not a user-selected wall-clock time. Each due occurrence freezes the last completed dates in the verified property calendar. Cron reconciles due work; the due time is not a guarantee that Google delivery completes at that instant. A changed property timezone requires attention rather than silently changing an existing schedule.
Status and recovery
Section titled “Status and recovery”The status route returns exactly schedule, latest and lastDelivered.
| Object | Fields |
|---|---|
schedule | id, revision, enabled, nextDueAt, timezone, windowDays, lastErrorCode |
latest, or null | id, dueAt, sourceRunId, destinationOrdinal, state, sourceAttempts, sourceNextAttemptAt, errorCode, exportId, exportState, exportAttempts, exportNextAttemptAt, exportErrorCode, visibleOrdinal |
lastDelivered, or null | pipelineId, destinationOrdinal, visibleOrdinal, completedAt |
Times are epoch milliseconds. Error fields and an unread visibleOrdinal can be
null. latest.id is the pipeline ID used by redrive. A pipeline moves through
source_pending, source_running and export_pending, then records succeeded,
superseded, failed or cancelled. Export state is tracked separately.
lastDelivered records the latest successful verification, not an unverified
provider response or a claim that the workbook was checked again just now.
Each phase has four durable attempts per budget. Transient failures retry with
bounded backoff; provider retry hints beyond the accepted policy become
retry_after_exceeds_policy. Duplicate delivery and lease recovery keep the same
source run, occurrence and destination ordinal. Source success requires the whole
window and expected run identities. A partial or superseded source does not advance
the Sheet’s trusted output. Export failure does not retract a source publication.
Failed occurrences can be explicitly redriven with {}. A redrive gives the failed
phase a fresh bounded budget and records the authenticated key ID as the actor.
It retains the occurrence, source identity, ordinal and any frozen export evidence;
it does not query newer data and relabel it as the same export. Unknown error text
is filtered, while fixed policy, capacity, permission and integrity codes remain
visible. See Errors.
Disabling increments the schedule revision and fences and cancels unfinished source and export work. It preserves successful history and does not erase the workbook. Already dispatched Google requests cannot be recalled. Re-enabling does not revive cancelled occurrences automatically.
The runtime captures data through a named private queryForExport service-binding
RPC. It is neither an HTTP route in this API nor an MCP tool. The gateway loads the
export’s persisted scope and lease, calls the same query implementation as REST and
MCP, and requires the planned source publication. Frozen export evidence retains
the normal provider_may_revise_recent_data and not_independently_reconciled
limitations.