---
title: "Get a domain's integration surface document"
method: GET
path: "/api/{domain}/surface"
tags: ["detect"]
---

# Get a domain's integration surface document

`GET /api/{domain}/surface`

Return the integration surface document that powers a domain page. The durable discovery result from KV wins when it exists; otherwise the endpoint returns the bundled baseline discovery JSON for that domain. The response lists the service's MCP, REST/OpenAPI, GraphQL, and CLI surfaces with stable slugs and authentication metadata. A 404 means integrations.sh has no stored or baseline surface document for the domain.

## Path parameters

- `domain` string, required

## Response `200`

Success

- object
  - `version` 3, required
  - `domain` string, required
  - `detect` unknown
  - `summary` string, nullable
  - `description` string, nullable
  - `discoveredAt` string, nullable
  - `credentials` object, nullable
  - `surfaces` union[], required
    - union — One integration surface. Per-`type` fields: http carries spec/url/patch; graphql carries url+spec; mcp carries url+transports; cli carries packages+command.
      - object — A REST/HTTP API, with or without an OpenAPI spec (spec present ⇒ machine-readable).
        - `type` 'http', required
        - `spec` string, nullable — OpenAPI doc URL — a POINTER, never inlined. Absent = specless REST; auth mechanics are then http/unknown, not spec.
        - `specAlternates` string[], nullable — Additional machine-readable spec documents for the SAME API in other formats (e.g. the YAML twin of a JSON OpenAPI doc).
        - `url` string, nullable — Base URL — when there's no spec, or not derivable from the spec's `servers`.
        - `patch` unknown
        - `slug` string, required — Stable identity and URL segment (/{domain}/{slug}/). Assigned SERVER-SIDE at record time (slugified name, deduped within the result) — the model never produces it. On re-discovery, a surface matching a previous one by locator (url/spec/command) KEEPS its prior slug even if renamed, so links never break.
        - `name` string, required — Display name. NOT identity — may change across runs; `slug` is the stable key.
        - `docs` string, nullable — Human docs URL.
        - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
          - object
            - `via` 'detected', required
            - `signal` string, required — A re-verifiable machine signal the service publishes (e.g. '.well-known/api-catalog', 'oauth-protected-resource', 'openapi:securitySchemes').
            - `verifiedAt` string, nullable — ISO timestamp the signal was last re-verified — detected facts age independently of the run that first found them.
          - object
            - `via` 'discovered', required
            - `evidence` string[], required — Doc URLs the agent read to confirm this. Point-in-time, prose-derived.
          - object
            - `via` 'declared', required
            - `source` string, required — The owner-published integrations.json URL that declared this surface or auth entry.
        - `auth` union, required — A surface's auth requirement: none | required | unknown.
          - object — Confirmed public — no credential needed. `basis.via:detected` (a probe got a clean unauthenticated response) outranks `discovered` (the docs said so).
            - `status` 'none', required
            - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
              - …
          - object
            - `status` 'required', required
            - `entries` object[], required — OR alternatives — at least one is needed.
              - …
          - object — Auth not yet determined (NOT the same as public).
            - `status` 'unknown', required
        - `requiredHeaders` object[], nullable
          - `name` string, required
          - `source` union, required
            - object
              - …
            - object
              - …
          - `description` string, nullable
        - `variables` object[], nullable
          - `name` string, required — A token substituted wherever `{name}` appears in the surface url (e.g. {project_ref} → {project_ref}.supabase.co).
          - `in` 'url' | 'header' | 'query', nullable — Default 'url' (templated into the url, incl. hostname). Set only when it goes elsewhere.
          - `resolveFrom` string, nullable
          - `description` string, nullable
        - `notes` string, nullable
      - object
        - `type` 'graphql', required
        - `url` string, nullable — Expected — a GraphQL schema has no endpoint, so this is how you reach it.
        - `spec` string, nullable — 'introspection' or an SDL URL.
        - `specAlternates` string[], nullable — Additional machine-readable spec documents for the SAME API in other formats (e.g. the YAML twin of a JSON OpenAPI doc).
        - `slug` string, required — Stable identity and URL segment (/{domain}/{slug}/). Assigned SERVER-SIDE at record time (slugified name, deduped within the result) — the model never produces it. On re-discovery, a surface matching a previous one by locator (url/spec/command) KEEPS its prior slug even if renamed, so links never break.
        - `name` string, required — Display name. NOT identity — may change across runs; `slug` is the stable key.
        - `docs` string, nullable — Human docs URL.
        - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
          - object
            - `via` 'detected', required
            - `signal` string, required — A re-verifiable machine signal the service publishes (e.g. '.well-known/api-catalog', 'oauth-protected-resource', 'openapi:securitySchemes').
            - `verifiedAt` string, nullable — ISO timestamp the signal was last re-verified — detected facts age independently of the run that first found them.
          - object
            - `via` 'discovered', required
            - `evidence` string[], required — Doc URLs the agent read to confirm this. Point-in-time, prose-derived.
          - object
            - `via` 'declared', required
            - `source` string, required — The owner-published integrations.json URL that declared this surface or auth entry.
        - `auth` union, required — A surface's auth requirement: none | required | unknown.
          - object — Confirmed public — no credential needed. `basis.via:detected` (a probe got a clean unauthenticated response) outranks `discovered` (the docs said so).
            - `status` 'none', required
            - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
              - …
          - object
            - `status` 'required', required
            - `entries` object[], required — OR alternatives — at least one is needed.
              - …
          - object — Auth not yet determined (NOT the same as public).
            - `status` 'unknown', required
        - `requiredHeaders` object[], nullable
          - `name` string, required
          - `source` union, required
            - object
              - …
            - object
              - …
          - `description` string, nullable
        - `variables` object[], nullable
          - `name` string, required — A token substituted wherever `{name}` appears in the surface url (e.g. {project_ref} → {project_ref}.supabase.co).
          - `in` 'url' | 'header' | 'query', nullable — Default 'url' (templated into the url, incl. hostname). Set only when it goes elsewhere.
          - `resolveFrom` string, nullable
          - `description` string, nullable
        - `notes` string, nullable
      - object
        - `type` 'mcp', required
        - `url` string, nullable — The MCP connect endpoint (NOT a docs page).
        - `transports` string[], nullable — streamable-http | sse (server.json `remotes[].type`).
        - `slug` string, required — Stable identity and URL segment (/{domain}/{slug}/). Assigned SERVER-SIDE at record time (slugified name, deduped within the result) — the model never produces it. On re-discovery, a surface matching a previous one by locator (url/spec/command) KEEPS its prior slug even if renamed, so links never break.
        - `name` string, required — Display name. NOT identity — may change across runs; `slug` is the stable key.
        - `docs` string, nullable — Human docs URL.
        - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
          - object
            - `via` 'detected', required
            - `signal` string, required — A re-verifiable machine signal the service publishes (e.g. '.well-known/api-catalog', 'oauth-protected-resource', 'openapi:securitySchemes').
            - `verifiedAt` string, nullable — ISO timestamp the signal was last re-verified — detected facts age independently of the run that first found them.
          - object
            - `via` 'discovered', required
            - `evidence` string[], required — Doc URLs the agent read to confirm this. Point-in-time, prose-derived.
          - object
            - `via` 'declared', required
            - `source` string, required — The owner-published integrations.json URL that declared this surface or auth entry.
        - `auth` union, required — A surface's auth requirement: none | required | unknown.
          - object — Confirmed public — no credential needed. `basis.via:detected` (a probe got a clean unauthenticated response) outranks `discovered` (the docs said so).
            - `status` 'none', required
            - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
              - …
          - object
            - `status` 'required', required
            - `entries` object[], required — OR alternatives — at least one is needed.
              - …
          - object — Auth not yet determined (NOT the same as public).
            - `status` 'unknown', required
        - `requiredHeaders` object[], nullable
          - `name` string, required
          - `source` union, required
            - object
              - …
            - object
              - …
          - `description` string, nullable
        - `variables` object[], nullable
          - `name` string, required — A token substituted wherever `{name}` appears in the surface url (e.g. {project_ref} → {project_ref}.supabase.co).
          - `in` 'url' | 'header' | 'query', nullable — Default 'url' (templated into the url, incl. hostname). Set only when it goes elsewhere.
          - `resolveFrom` string, nullable
          - `description` string, nullable
        - `notes` string, nullable
      - object
        - `type` 'cli', required
        - `packages` object[], nullable — Install options (server.json `packages` shape).
          - `registryType` string, required — npm | pypi | oci | brew | …
          - `identifier` string, required
          - `runtimeHint` string, nullable — npx | uvx | …
        - `command` string, nullable — The command name, e.g. 'wrangler'.
        - `slug` string, required — Stable identity and URL segment (/{domain}/{slug}/). Assigned SERVER-SIDE at record time (slugified name, deduped within the result) — the model never produces it. On re-discovery, a surface matching a previous one by locator (url/spec/command) KEEPS its prior slug even if renamed, so links never break.
        - `name` string, required — Display name. NOT identity — may change across runs; `slug` is the stable key.
        - `docs` string, nullable — Human docs URL.
        - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
          - object
            - `via` 'detected', required
            - `signal` string, required — A re-verifiable machine signal the service publishes (e.g. '.well-known/api-catalog', 'oauth-protected-resource', 'openapi:securitySchemes').
            - `verifiedAt` string, nullable — ISO timestamp the signal was last re-verified — detected facts age independently of the run that first found them.
          - object
            - `via` 'discovered', required
            - `evidence` string[], required — Doc URLs the agent read to confirm this. Point-in-time, prose-derived.
          - object
            - `via` 'declared', required
            - `source` string, required — The owner-published integrations.json URL that declared this surface or auth entry.
        - `auth` union, required — A surface's auth requirement: none | required | unknown.
          - object — Confirmed public — no credential needed. `basis.via:detected` (a probe got a clean unauthenticated response) outranks `discovered` (the docs said so).
            - `status` 'none', required
            - `basis` union, required — How we learned a thing exists. `detected` = asserted by a machine signal (high trust, re-verifiable); `discovered` = the agent read it from docs; `declared` = published by the site owner.
              - …
          - object
            - `status` 'required', required
            - `entries` object[], required — OR alternatives — at least one is needed.
              - …
          - object — Auth not yet determined (NOT the same as public).
            - `status` 'unknown', required
        - `requiredHeaders` object[], nullable
          - `name` string, required
          - `source` union, required
            - object
              - …
            - object
              - …
          - `description` string, nullable
        - `variables` object[], nullable
          - `name` string, required — A token substituted wherever `{name}` appears in the surface url (e.g. {project_ref} → {project_ref}.supabase.co).
          - `in` 'url' | 'header' | 'query', nullable — Default 'url' (templated into the url, incl. hostname). Set only when it goes elsewhere.
          - `resolveFrom` string, nullable
          - `description` string, nullable
        - `notes` string, nullable
  - `usedLlm` boolean, nullable

## Other responses

- `404` — No stored or baseline surface document exists for the domain.

---

[API](https://skmtc.dev/integrations/apis/integrations-sh.md) · [All operations](https://skmtc.dev/integrations/apis/integrations-sh/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/integrations/integrations-sh/revisions/1c66e9265db5/schema)
