CloudQuery External Syncs API

The external-syncs API from CloudQuery — 9 operation(s) for external-syncs.

Operations 9

POST /external-syncs Platform create external sync #
GET /external-syncs/whoami Platform whoami external sync #
GET /external-syncs/supported-source-versions Platform list supported source versions #
GET /external-syncs/recommended-source-config Platform get recommended source config #
POST /platform-destination/token Platform create platform destination token #
POST /external-syncs/{external_sync_id}/files/presign Platform presign external sync file #
POST /external-syncs/{external_sync_id}/progress Platform report external sync progress #
GET /external-sync-runs Platform list external sync runs #
GET /external-sync-runs/{external_sync_id} Platform get external sync run #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cloudquery:cloudquery-external-syncs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

cloudquery-external-syncs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  contact:
    email: support@cloudquery.io
    name: CloudQuery Support Team
    url: https://cloudquery.io
  description: 'Welcome to the CloudQuery Platform API documentation! This API can be used to interact with the CloudQuery platform. As a user, the API allows you to search the CloudQuery asset inventory, run SQL queries against the data warehouse, save and load searches, and much more. As an administrator, it allows you to manage your teams, syncs, and other objects.

    ### Authentication

    The API is secured using bearer tokens. To get started, you can generate an API key for your Platform deployment from your platform dashboard. For a step-by-step guide, see: https://www.cloudquery.io/docs/cli/managing-cloudquery/deployments/generate-api-key.

    The base URL for the API depends on where your CloudQuery Platform is hosted. If running locally, this is usually http://localhost:3000/api. In a production deployment it should be an HTTPS URL. For purposes of illustration, we will assume the platform instance is available at https://cloudquery.mycompany.com. In this case, the base API endpoint will be https://cloudquery.mycompany.com/api.

    ### Example Request

    To test your connection to the API, we can use the `/plugins` endpoint. For example:

    `curl -v -H "Authorization: Bearer $CLOUDQUERY_API_KEY" \ https://cloudquery.mycompany.com/api/plugins`'
  license:
    name: MIT
    url: https://spdx.org/licenses/MIT
  termsOfService: https://www.cloudquery.io/terms
  title: CloudQuery Platform OpenAPI Spec External Syncs API
  version: 1.0.0
security:
- bearerAuth: []
- cookieAuth: []
tags:
- name: external-syncs
paths:
  /external-syncs:
    post:
      description: 'Open a new external sync. The server assigns and returns a sync ID that the client includes on subsequent presign requests. This endpoint is idempotent per `(tenant, invocation_id)`: calling it again with the same invocation_id returns the existing sync.'
      operationId: PlatformCreateExternalSync
      tags:
      - external-syncs
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - invocation_id
              - sources
              properties:
                invocation_id:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: Client-supplied identifier for this CLI invocation. Typically a UUID generated by the CloudQuery CLI. Used as an idempotency key.
                  example: 4c3ea5cd-7f3d-4dfd-8ea8-c0b29eadac69
                sources:
                  type: array
                  minItems: 1
                  description: 'The source plugins this sync will upload, reported by the CloudQuery CLI. Required: a sync must declare its sources so the platform can reject (422) sources whose version the asset view can''t process before any data is uploaded.'
                  items:
                    type: object
                    required:
                    - name
                    - path
                    - version
                    properties:
                      name:
                        type: string
                        description: Configured source name (`_cq_source_name`); used only to identify the source in error messages.
                        example: aws
                      path:
                        type: string
                        description: Source plugin path the asset view keys support by.
                        example: cloudquery/aws
                      version:
                        type: string
                        description: Source plugin version (semver, `v`-prefixed).
                        example: v32.3.1
      responses:
        '201':
          description: Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformExternalSync'
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '422':
          $ref: '#/components/responses/PlatformUnprocessableEntity'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform create external sync
      x-summary-source: derived
  /external-syncs/whoami:
    get:
      description: Return the identity of the caller. Used by the CloudQuery Platform destination plugin to validate an API key at startup.
      operationId: PlatformWhoamiExternalSync
      tags:
      - external-syncs
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformExternalSyncWhoami'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform whoami external sync
      x-summary-source: derived
  /external-syncs/supported-source-versions:
    get:
      description: List the asset-view-pinned version for each supported source plugin — the newest version the platform can ingest (a source is supported from `.0.0` up to and including this version). The CloudQuery CLI uses this to warn before running a sync whose source version the platform can't process. Optionally filter to a single plugin path.
      operationId: PlatformListSupportedSourceVersions
      tags:
      - external-syncs
      parameters:
      - name: path
        in: query
        required: false
        description: Filter to a single source plugin path (e.g. `cloudquery/aws`). When set, the response contains only that path, or is empty if it isn't supported.
        schema:
          type: string
          example: cloudquery/aws
      responses:
        '200':
          description: Pinned version keyed by source plugin path.
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                example:
                  cloudquery/aws: v32.5.5
                  cloudquery/gcp: v14.2.1
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform list supported source versions
      x-summary-source: derived
  /external-syncs/recommended-source-config:
    get:
      description: 'Get a ready-to-write source spec the platform recommends for a source plugin: the plugin''s example config sanitized for platform syncs (placeholder auth-scope values removed, wired to the injected `platform` destination, tables set to the recommended list) at the platform''s pinned version. The CloudQuery CLI writes this as the scaffolded sync config instead of deriving one from the plugin docs. An empty `config` means the platform has no scaffold for the plugin, which the CLI reports as an error.'
      operationId: PlatformGetRecommendedSourceConfig
      tags:
      - external-syncs
      parameters:
      - name: path
        in: query
        required: true
        description: The source plugin path (e.g. `cloudquery/gcp`).
        schema:
          type: string
          example: cloudquery/gcp
      responses:
        '200':
          description: The recommended source spec for the plugin.
          content:
            application/json:
              schema:
                type: object
                required:
                - config
                properties:
                  config:
                    type: string
                    description: Ready-to-write CloudQuery source spec YAML. Empty when the platform has no scaffold for the plugin.
                  version:
                    type: string
                    description: The pinned source plugin version baked into the config.
                    example: v23.0.1
                  tables:
                    type: array
                    description: The table names baked into the config.
                    items:
                      type: string
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform get recommended source config
      x-summary-source: derived
  /platform-destination/token:
    post:
      description: 'Mint a short-lived (~7 days), signed platform-destination token (prefix `cqpd_`) for the caller''s tenant. The user pastes this token as their CloudQuery CLI credential: it authenticates plugin/usage calls to cloud (which verifies it offline) and `/external-syncs/*` on this platform — no host configuration. Any signed-in tenant user with write access can mint one for their own tenant, whatever their login method (local password, SAML, magic link); a tenant API key with write access works too, for CI (a default `ci`-role key cannot mint). It is a derived credential: the CLI re-mints it from the durable root (cloud login, a tenant API key, or a fresh tenant sign-in) as it nears expiry, so a leaked token expires within about a week. There is no per-token revocation — verification is offline on both stacks, against either of the tenant''s two external-sync secret slots. Rotating the secret demotes the outgoing one to the second slot as a grace window, so outstanding tokens keep working until a second rotation displaces it; two rotations revoke every outstanding token for the tenant. Disabling the user who minted a token does not invalidate it before it expires. Returned once.'
      operationId: PlatformCreatePlatformDestinationToken
      tags:
      - external-syncs
      responses:
        '201':
          description: Token minted
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                - token
                - expires_at
                properties:
                  token:
                    type: string
                    description: The signed `cqpd_` token. Shown once.
                  expires_at:
                    type: string
                    format: date-time
                    description: When the token expires.
                  plugin_version:
                    type: string
                    description: Recommended `cloudquery/platform` destination plugin version.
                    example: v1.0.0
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '422':
          $ref: '#/components/responses/PlatformUnprocessableEntity'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform create platform destination token
      x-summary-source: derived
  /external-syncs/{external_sync_id}/files/presign:
    post:
      description: Mint a short-lived presigned PUT URL for a single Parquet file belonging to an external sync. The client uses the returned URL to upload directly to the platform-owned S3 bucket without ever seeing AWS credentials.
      operationId: PlatformPresignExternalSyncFile
      tags:
      - external-syncs
      parameters:
      - name: external_sync_id
        in: path
        required: true
        description: The external sync ID returned from `POST /external-syncs`.
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - source_name
              - sync_group_id
              - table
              - content_type
              properties:
                sync_group_id:
                  type: integer
                  format: int64
                  minimum: 1
                  description: The `_cq_sync_group_id` value (time-based uint64) carried on rows from this sync. The platform encodes it in the object key so assetview's `(tenant, source, sync_group_id)` finalize key matches the row data — without it the staging-to-main promote wipes rows whose sgid disagrees with the path.
                  example: 20260415120000124
                source_name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: ^\.*[A-Za-z0-9_-][A-Za-z0-9_.-]*$
                  x-pattern-message: source_name may contain only letters, digits, '_', '.', or '-' (and not be all dots)
                  description: CloudQuery source plugin name the file's rows originate from (the value of `_cq_source_name`). Encoded into the object key so platform ingestion can key staging-table finalization by source. Restricted to an encoding-invariant charset so the S3 key the ingest pipeline parses matches what was written (S3 event notifications URL-encode keys).
                  example: aws
                table:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: ^\.*[A-Za-z0-9_-][A-Za-z0-9_.-]*$
                  x-pattern-message: table may contain only letters, digits, '_', '.', or '-' (and not be all dots)
                  description: CloudQuery table name this file is for. Used in the object key. Restricted to an encoding-invariant charset (see source_name).
                  example: aws_ec2_instances
                content_type:
                  type: string
                  description: The exact Content-Type the client will send with the PUT.
                  example: application/vnd.apache.parquet
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformExternalSyncPresignedFile'
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '404':
          $ref: '#/components/responses/PlatformNotFound'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform presign external sync file
      x-summary-source: derived
  /external-syncs/{external_sync_id}/progress:
    post:
      description: Report progress for an external sync. The platform destination plugin calls this periodically with running row counts while writing, and once with a terminal status (`completed`/`failed`) when the sync ends. Used to surface live progress and a final state for syncs the platform does not orchestrate. Counts are cumulative totals; omitted fields leave the last-reported value unchanged, and a terminal status is final (a later `started` won't reopen the sync).
      operationId: PlatformReportExternalSyncProgress
      tags:
      - external-syncs
      parameters:
      - name: external_sync_id
        in: path
        required: true
        description: The external sync ID returned from `POST /external-syncs`.
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
              - status
              properties:
                status:
                  type: string
                  enum:
                  - started
                  - completed
                  - failed
                  description: Current lifecycle state of the sync.
                  example: started
                rows:
                  type: integer
                  format: int64
                  minimum: 0
                  description: Total rows written so far across all tables.
                  example: 12345
                table_progress:
                  type: object
                  description: Per-table row counts, keyed by table name.
                  additionalProperties:
                    type: object
                    properties:
                      rows:
                        type: integer
                        format: int64
                        minimum: 0
      responses:
        '204':
          description: Progress recorded.
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '404':
          $ref: '#/components/responses/PlatformNotFound'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform report external sync progress
      x-summary-source: derived
  /external-sync-runs:
    get:
      description: List the team's external syncs (CLI runs uploaded to the platform), newest first. Read-only view for the frontend; the tenant is resolved from the host.
      operationId: PlatformListExternalSyncRuns
      tags:
      - external-syncs
      parameters:
      - $ref: '#/components/parameters/platform_per_page'
      - $ref: '#/components/parameters/platform_page'
      - name: status
        in: query
        required: false
        description: Filter by lifecycle status.
        schema:
          type: string
          enum:
          - started
          - finalizing
          - completed
          - failed
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                type: object
                required:
                - items
                - metadata
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/PlatformExternalSync'
                  metadata:
                    $ref: '#/components/schemas/PlatformListMetadata'
        '400':
          $ref: '#/components/responses/PlatformBadRequest'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform list external sync runs
      x-summary-source: derived
  /external-sync-runs/{external_sync_id}:
    get:
      description: Get a single external sync, including its live progress and lifecycle status. The tenant is resolved from the host.
      operationId: PlatformGetExternalSyncRun
      tags:
      - external-syncs
      parameters:
      - name: external_sync_id
        in: path
        required: true
        description: The external sync ID returned from `POST /external-syncs`.
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformExternalSync'
        '401':
          $ref: '#/components/responses/PlatformRequiresAuthentication'
        '404':
          $ref: '#/components/responses/PlatformNotFound'
        '500':
          $ref: '#/components/responses/PlatformInternalError'
      summary: Platform get external sync run
      x-summary-source: derived
components:
  schemas:
    PlatformExternalSyncPresignedFile:
      description: A single presigned S3 PUT URL to upload one Parquet file to.
      type: object
      required:
      - url
      - key
      - required_headers
      - expires_at
      properties:
        url:
          type: string
          format: uri
          description: The presigned URL. Issue an HTTP PUT to this URL with the file body.
        key:
          type: string
          description: The S3 object key the presigned URL writes to. Recorded so the platform can locate the uploaded file without listing the bucket.
          example: syncs/tenant/11111111-1111-1111-1111-111111111111/external/22222222-2222-2222-2222-222222222222/aws_ec2_instances___3a.parquet
        required_headers:
          description: Headers that MUST be sent with the PUT request exactly as given. These are bound into the signature; replaying them verbatim is required.
          type: object
          additionalProperties:
            type: string
          example:
            Content-Type: application/vnd.apache.parquet
        expires_at:
          type: string
          format: date-time
          description: The absolute instant after which the URL stops being valid.
          example: '2026-04-15T14:43:20Z'
    PlatformExternalSync:
      description: 'A sync that a user is running with their own local CloudQuery CLI and uploading to the CloudQuery Platform through the presigned-URL proxy. Unlike managed syncs, the platform does not schedule these: the CLI owns the lifecycle and only the uploaded files land on the platform.'
      type: object
      required:
      - id
      - invocation_id
      - created_at
      properties:
        id:
          type: string
          format: uuid
          description: Server-assigned ID of the external sync. Include this in subsequent presign requests.
        invocation_id:
          type: string
          description: Client-supplied identifier used to make sync creation idempotent.
          example: 4c3ea5cd-7f3d-4dfd-8ea8-c0b29eadac69
        created_at:
          type: string
          format: date-time
          example: '2026-04-15T14:28:20Z'
        status:
          type: string
          enum:
          - started
          - finalizing
          - completed
          - failed
          description: Lifecycle state. The destination plugin reports `started`/`failed`; when it reports done the platform records `finalizing` until the uploaded data is ingested, then flips to `completed`.
        rows:
          type: integer
          format: int64
          description: Total rows written across all tables.
        table_progress:
          type: object
          description: Per-table row counts, keyed by table name.
          additionalProperties:
            type: integer
            format: int64
        updated_at:
          type: string
          format: date-time
          description: Last time progress was reported.
        finished_at:
          type: string
          format: date-time
          description: When the sync reached a terminal status, if it has.
    PlatformListMetadata:
      required:
      - page_size
      properties:
        total_count:
          type: integer
        last_page:
          type: integer
        page_size:
          type: integer
        time_ms:
          type: integer
        next_cursor:
          type: string
          description: 'Opaque cursor for the next page when using keyset pagination. Present only

            for keyset-eligible list queries (default order, no group_by); omitted on

            the last page. Pass it back as the `cursor` query parameter.

            '
    PlatformExternalSyncWhoami:
      description: Identity of the CloudQuery Platform tenant the request is authenticated as.
      type: object
      required:
      - tenant_id
      properties:
        tenant_id:
          type: string
          format: uuid
          description: The UUID of the tenant this API key belongs to.
        warning:
          type: string
          description: Advisory message the client should surface to the user verbatim (e.g. the presented token is about to expire). Omitted when there is nothing to warn about.
        plugin_version:
          type: string
          description: Recommended cloudquery/platform destination plugin version. The CLI pins the injected destination to it — notably in the headless flow, which only calls whoami and never mints.
          example: v1.0.0
    PlatformFieldError:
      allOf:
      - $ref: '#/components/schemas/PlatformBasicError'
      - properties:
          errors:
            items:
              type: string
            type: array
          field_errors:
            additionalProperties:
              type: string
            type: object
        type: object
    PlatformBasicError:
      additionalProperties: false
      description: Basic Error
      required:
      - message
      - status
      properties:
        message:
          type: string
        status:
          type: integer
      title: Basic Error
      type: object
  responses:
    PlatformInternalError:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformBasicError'
      description: Internal Error
    PlatformRequiresAuthentication:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformBasicError'
      description: Requires authentication
    PlatformBadRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformFieldError'
      description: Bad request
    PlatformNotFound:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformBasicError'
      description: Resource not found
    PlatformUnprocessableEntity:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PlatformFieldError'
      description: UnprocessableEntity
  parameters:
    platform_page:
      description: Page number of the results to fetch
      in: query
      name: page
      required: false
      schema:
        default: 1
        minimum: 1
        type: integer
        format: int64
    platform_per_page:
      description: The number of results per page (max 1000).
      in: query
      name: per_page
      required: false
      schema:
        default: 100
        maximum: 1000
        minimum: 1
        type: integer
        format: int64
  securitySchemes:
    bearerAuth:
      scheme: bearer
      type: http
    basicAuth:
      scheme: basic
      type: http
    cookieAuth:
      scheme: cookie
      type: http
x-provenance:
  method: harvested
  publisher: CloudQuery
  source: https://platform-multi-tenant-api-docs.cloudquery.io/openapi.json
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)