API reference
Trigger a bounded extraction run
POST /v1/syncs
Starts, resumes or returns an extraction run for one connection and a window of at most 31 days.
Idempotency-Key is required. Reusing a key with the same window resumes or
returns the durable run rather than starting a second one; changed intent
needs a new key. At most one live lease may execute the same exact workspace,
connection, property and date window. A different key contending for that
window receives window_in_progress before a run row, sequence or provider
request is allocated; retry that same key after the current run finishes or
its lease expires. Partly overlapping windows remain independent.
Strict calendar and interval validation occurs before extraction. Completion is checked in the property’s returned timezone; there is no earlier UTC completion gate. Publication compares the immutable extraction time first; the creation sequence is only the deterministic tie-break for equal millisecond timestamps. Both values are checked atomically against the current head’s matching source run.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Header Parameters
Section titled “Header Parameters ”8–128 characters from A-Za-z0-9._:-. Identifies one logical extraction.
Request Body required
Section titled “Request Body required ”The sync request body. Unknown fields are rejected rather than ignored.
MetricQuery deliberately repeats these five fields rather than composing
this schema with allOf: additionalProperties is evaluated only against
the properties in the same schema object, so an allOf branch carrying
additionalProperties: false would reject the query body’s metric and
dimensions and make the composed schema match nothing.
object
Must equal the API key’s own workspace.
GA4 numeric property id, as a string.
Calendar date in the property’s reporting timezone.
Inclusive. The closed interval must contain 1–31 days. For sync it must also be before today in the property’s returned timezone.
Example
{ "workspaceId": "your_workspace", "connectionId": "your_connection", "propertyId": "123456789", "startDate": "2026-08-31", "endDate": "2026-09-04"}Responses
Section titled “ Responses ”The run reached completed, partial or superseded. HTTP 200 alone does not imply full publication; check state and the expected publishedDates.
object
errorCode is conditionally present: required for failed and forbidden in
every other state. The four nullable fields are always present — the gateway
rejects an upstream response that omits them.
Completed, partial and superseded records have non-null timezone and quality.
Completed and superseded quality is reliable (both limitation flags false and
no sampling); partial quality names at least one thresholding, loss or sampling
limitation. A failed record retains null completion/publication fields and a
required classified errorCode.
object
The run is in progress — pending, extracting, raw_committed or
loaded. Poll GET /v1/syncs/{runId}; a successful polling GET returns
200 even while the run remains in progress, so inspect its state.
object
errorCode is conditionally present: required for failed and forbidden in
every other state. The four nullable fields are always present — the gateway
rejects an upstream response that omits them.
Completed, partial and superseded records have non-null timezone and quality.
Completed and superseded quality is reliable (both limitation flags false and
no sampling); partial quality names at least one thresholding, loss or sampling
limitation. A failed record retains null completion/publication fields and a
required classified errorCode.
object
invalid_json — the body is absent, not valid JSON, or not valid UTF-8.
invalid_request, invalid_window, invalid_idempotency_key,
invalid_provider_request, or incomplete_day when the window includes a
day still in progress in the property’s timezone.
invalid_query — the URL carried a query delimiter, including a bare
?. The route table checks this before it reads the body, so
POST /v1/syncs?anything is refused here rather than at 404.
object
object
object
unauthorized — missing, unknown, expired or revoked key.
object
object
object
Headers
Section titled “Headers ”forbidden — the key lacks sync:write, or the window’s workspace is not the key’s.
object
object
object
method_not_allowed — Allow names the method this route accepts.
object
object
object
Headers
Section titled “Headers ”lease_lost, idempotency_conflict (the key was used for a different
window), window_in_progress (another key owns a live lease for the
exact window), or publication_rejected.
object
object
object
request_too_large — REST bodies are capped at 4 KiB.
object
object
object
unsupported_media_type unless the body is application/json, or
unsupported_encoding for any Content-Encoding other than identity.
Both are the gateway’s own; json_required is the same refusal raised by
the sync service and passed through, and is classified here so that it
cannot reach a caller as an unclassified failure.
object
object
object
invalid_lease_config — the sync service is misconfigured (its lease
duration is outside the permitted range). Not retryable; it needs an
operator.
Documented because the gateway classifies it, but the deployed sync service does not override the default lease duration, so it should not reach a caller.
object
object
object
The run could not obtain trustworthy upstream data. Nothing is published, and any previous complete result is left intact. The code names which trust condition failed. This is the complete set — a 502 carries one of these and nothing else:
The provider could not be reached or would not answer:
provider_auth_failed, provider_unavailable, provider_error.
The provider answered, but the report itself cannot be trusted:
malformed_report, malformed_metadata, malformed_row,
unexpected_schema, empty_report_reason, restricted_report,
changing_report.
The report is not the whole of what was asked for, or does not agree
with itself: incomplete_report, row_count_mismatch, row_count_limit,
page_limit, duplicate_date.
The report could not be read out of the provider’s response:
invalid_extraction, incomplete_extraction.
The raw evidence behind the run could not be written or could not be
shown to be the evidence for this run: raw_commit_failed,
raw_integrity_failure, raw_identity_mismatch, raw_missing.
The verified data could not be loaded into analytics storage:
analytics_load_failed.
object
object
object
sync_unavailable, auth_unavailable, credential_unavailable,
credential_configuration_unavailable, credential_busy,
provider_rate_limited, ledger_unavailable, analytics_load_unavailable
or invalid_clickhouse_config. Retry with the same idempotency key.