---
title: "Create Instance From Openapi"
method: POST
path: "/api/integrations/instances/from-openapi"
tags: ["integrations"]
---

# Create Instance From Openapi

`POST /api/integrations/instances/from-openapi`

## Request

- Base URL: `https://app.thinqos.com` (the document declares no server; this is the origin it was published from)
- URL: `https://app.thinqos.com/api/integrations/instances/from-openapi`
- Auth: none declared

CONNECT-A-CAPABILITY FLOW step 1 (REST/OpenAPI variant): define the integration here, then
    install it for the current identity with integration_install. Add a new REST 'connected tool'
    (MCP integration) owned by the calling identity, built from an OpenAPI spec URL. thinqOS fetches
    the spec, generates the tool manifest, encrypts any provided secret server-side, and probes the
    upstream. Mirrors the Connected Tools screen's 'Import from OpenAPI' flow. For a secured API
    pass the bearer/API key as plaintext_secret (never stored in the clear). Fails with a clear
    message if the spec is unreachable, the manifest is invalid, or a registration with that name
    already exists.
connection_mode is required, no default: pass 'shared' (one credential the
    whole folder uses) or 'per_caller' (each identity connects and uses their own credential) — you
    must always pick one.
For a secured spec (bearer or API-key auth) with no secret available yet
    -- e.g. building a public Discover template without pasting your own production key -- pass
    allow_unconnected=True to create the row unauthenticated; the auth scheme is still recorded and
    the installer supplies their own credential at connect time. Omitting both a secret and
    allow_unconnected=True fails with a clear error rather than silently creating an unusable row.

## Headers

- `x-impersonate-identity-id` string, nullable

## Request body

- OpenAPICreateRequest
  - `openapi_url` string, required
  - `name` string, required
  - `selected_auth_scheme` string, nullable
  - `connection_mode` 'shared' | 'per_caller', required
  - `description` string, nullable
  - `plaintext_secret` string, nullable
  - `auth_secret_ref` string, nullable
  - `secret_refs` object
  - `secret_values` object
  - `credential_fit_override_reason` string, nullable
  - `allow_unconnected` boolean

## Response `201`

Successful Response

- RegistrationCreateResponse: Returned by POST /api/integrations/instances. Same shape as RegistrationOut with one extra field: ``test_result``. Subclassing rather than wrapping keeps the top-level shape stable for existing consumers - only the new ``test_result`` field is additive. ``test_result`` is None when the create-time probe was skipped for OAuth registrations; their connection state lives behind a post-create Connect flow. ``credential_fit_warning`` (TOS-990 Phase 1b) is set when this integration's access nature is 'service' but it was stood up on a user-OAuth credential and the author did NOT pass a ``credential_fit_override_reason``. Additive, optional, warn-only — creation always succeeds.
  - `id` string, uuid, required
  - `definition_id` string, uuid, required
  - `definition_slug` string, nullable
  - `account_capture_source` 'gmail' | 'google-calendar', nullable
  - `library_id` string, uuid, nullable
  - `library_name` string, nullable
  - `my_role` string, nullable
  - `connection_mode` 'shared' | 'per_caller', required
  - `alias` string, required
  - `name` string, required
  - `transport` 'http' | 'sse' | 'stdio_bridge' | 'rest', required
  - `base_url` string, required
  - `display_icon_url` string, nullable
  - `display_icon_is_inferred` boolean
  - `auth_kind` 'none' | 'bearer' | 'api_key_header' | 'oauth2' | 'gcp_oidc' | 'gcp_service_account' | 'github_app', required
  - `auth_header_name` string, nullable, required
  - `auth_secret_ref` string, nullable
  - `description` string, nullable, required
  - `trusted` boolean, required
  - `enabled` boolean, required
  - `health_check_tool` string, nullable, required
  - `health_check_arguments` object
  - `health_check_declined` boolean
  - `health_check_decline_reason` string, nullable
  - `refresh_seconds` integer, required
  - `rate_limit_per_minute` integer, nullable, required
  - `request_max_bytes` integer, required
  - `response_max_bytes` integer, required
  - `talkable` boolean
  - `stdio_command` string, nullable
  - `stdio_args` unknown[]
    - unknown
  - `stdio_env` object
  - `rest_manifest` object, nullable
  - `rest_openapi_source_url` string, nullable
  - `icon_url` string, nullable
  - `icon_data_url` string, nullable
  - `secret_refs` object
  - `config_version` integer, nullable
  - `tool_overrides` object
  - `installed_template_version` integer, nullable
  - `latest_template_version` integer, nullable
  - `template_update_available` boolean
  - `published_as_template` boolean
  - `published_template_version` integer, nullable
  - `published_template_visibility` string, nullable
  - `oauth_resource_url` string, nullable
  - `oauth_authorization_url` string, nullable
  - `oauth_token_url` string, nullable
  - `oauth_client_id` string, nullable
  - `oauth_scopes` string, nullable
  - `oauth_pkce_enabled` boolean
  - `oauth_client_secret_set` boolean
  - `oauth_requires_manual_client` boolean
  - `oauth_token_expires_at` string, date-time, nullable
  - `oauth_connected` boolean
  - `oauth_granted_scopes` string, nullable
  - `oauth_principal` object, nullable
  - `account_identifiable` boolean, nullable
  - `permissions` ConnectionPermissionOut[], nullable
    - `key` string, required
    - `label` string, required
  - `permissions_summary` string, nullable
  - `provider_name` string, nullable
  - `provider_consent_url` string, nullable
  - `sign_in_note` string, nullable
  - `owned_by_viewer` boolean, nullable
  - `org_naming_mismatch_warning` string, nullable
  - `credential_connected` boolean
  - `credential_status` 'connected' | 'needs_reconnect' | 'admin_repair' | 'unreachable' | 'missing'
  - `viewer_removal` 'self' | 'other', nullable
  - `credential_last_auth_error` string, nullable
  - `credential_failure_code` string, nullable
  - `access_nature` string, nullable
  - `reauth_class` string, nullable
  - `server_name` string, nullable
  - `server_version` string, nullable
  - `protocol_version` string, nullable
  - `server_capabilities` object, nullable
  - `server_instructions` string, nullable
  - `last_test_success` boolean, nullable
  - `last_test_tool_count` integer, nullable
  - `last_test_error` string, nullable
  - `last_test_duration_ms` integer, nullable
  - `last_test_at` string, date-time, nullable
  - `test_result` ConnectionTestResult: Returned by RegistrationService.test_connection.
    - `success` boolean, required
    - `tool_count` integer
    - `error` string, nullable
    - `duration_ms` integer, required
    - `failure_kind` string, nullable
    - `evidence` 'credential' | 'transport' | 'none'
    - `http_status` integer, nullable
    - `provider_reason` string, nullable
    - `missing_scopes` string[], nullable
    - `probe_is_error` boolean
    - `account_mismatch` boolean
    - `failure_code` string, nullable
    - `diagnostic_reference` string, nullable
    - `tool_names` string[], nullable
    - `health` ConnectionHealthOut: Health of one connection, rendered without the client inventing anything. ``status`` carries the Connected-filter buckets directly (``ready`` / ``degraded`` / ``needs_attention`` / ``unknown``), so the list filters and the degraded/failure screens all read one field. ``credential_status`` keeps the underlying evidence-ladder value for callers that need it. ``unknown`` means CONNECTED BUT NOT YET MEASURED — a credential-free integration that owns no connection row, or a connection probed before the rollup existed. There is no evidence of a problem, so it belongs in the **Ready** filter bucket; render the detail as "Not checked yet" rather than showing ``summary`` (which would read "0 of 0 tools available"). It is a distinct value rather than being folded into ``ready`` because claiming "no capability is failing" when nothing was measured is a fabrication.
      - `status` 'ready' | 'degraded' | 'needs_attention' | 'unknown', required
      - `credential_status` 'connected' | 'needs_reconnect' | 'admin_repair' | 'unreachable' | 'missing', required
      - `healthy_tools` integer, required
      - `total_tools` integer, required
      - `affected_tools` AffectedToolOut[]
        - `name` string, required
        - `reason` string, required
        - `failure_code` string, nullable
        - `evidence` 'probe' | 'telemetry', required
        - `observed_at` string, date-time, nullable
      - `healthy_summary` string, required
      - `summary` string, required
      - `checked_at` string, date-time, nullable
      - `failure` ConnectionFailureDetail: The four named fields the connection-failure screen renders, plus the action. Populated from the closed ``IntegrationFailureCode`` taxonomy (TOS-2708), so every failure category — OAuth denial, wrong account, invalid/expired key, missing scopes, failed safe probe, rate limit, unreachable endpoint, partially unavailable tools — resolves to named copy rather than an error string the user has to interpret.
        - `code` string, required
        - `failed_check` string, required
        - `cause` string, required
        - `preserved` string, required
        - `diagnostic_reference` string, required
        - `next_action` string, required
  - `credential_fit_warning` string, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/thinqos/apis/thinqos-api.md) · [All operations](https://skmtc.dev/thinqos/apis/thinqos-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thinqos/apis/thinqos-api/revisions/5387b4ded614?raw)
