APIs.io Provider Control API

Claim, correct and improve your own listing. Most operations require the Influence plan; reporting that our data is wrong is free and always will be.

Operations 13

POST /providers/{slug}/correction Report that the catalog has this provider wrong #
POST /providers/{slug}/claim Create or return your claim on this listing #
POST /providers/{slug}/facts Create or update your pending fact correction for this listing #
POST /providers/{slug}/submit Create or update an artifact pointer for this listing #
POST /providers/{slug}/visibility Request restricted listing or removal #
POST /providers/{slug}/dispute Dispute something the rating says about this provider #
POST /providers/{slug}/generate What APIs.io can generate on this provider's behalf #
POST /providers/{slug}/projection What a set of fixes would move the score to #
GET /providers/{slug}/remediation The ranked, costed punch list for this provider #
GET /providers/{slug}/gates Band gates for this provider, and what is unmet #
GET /providers/{slug}/rating/checks Per-check Kin Score results for this provider #
POST /checks Ask for a provider, industry, tag or area to be re-profiled #
POST /gaps/report Tell us what you looked for and did not find #

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/apis-io-provider-control-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

apis-io-provider-control-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: APIs.io Provider Control API
  version: 1.0.0
  description: 'The surface a provider uses to act on their own listing: claim it, correct it, submit artifacts, dispute a finding, ask what to fix, and simulate a fix before doing the work.'
  contact:
    name: API Evangelist
    url: https://apis.io
  license:
    name: CC BY 4.0
    url: https://creativecommons.org/licenses/by/4.0/
servers:
- url: https://apis.io/api/v1
  description: Production server.
tags:
- name: Provider Control
  description: Claim, correct and improve your own listing. Most operations require the Influence plan; reporting that our data is wrong is free and always will be.
paths:
  /providers/{slug}/correction:
    post:
      operationId: reportCorrection
      summary: Report that the catalog has this provider wrong
      description: 'Free, unmetered and keyless. Correcting our own error is not a paid feature.


        NOT IDEMPOTENT. Each call files a new correction; sending the same body twice queues it twice. There is no caller-declared match key and the response does not distinguish a created record from an amended one, because amending is not currently possible.'
      x-tier: free
      x-mcp-tool: report_correction
      tags:
      - Provider Control
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - wrong
              properties:
                wrong:
                  type: string
                  description: What is incorrect. Name the field if you can.
                correct:
                  type: string
                  description: What it should say instead.
                evidence:
                  type: string
                  format: uri
                  description: A URL that shows it — your own docs or site. This is what makes a correction actionable rather than a claim.
                field:
                  type: string
                  description: Optional field name.
                  enum:
                  - website
                  - image
                  - api_count
                  - tags
                  - score
                  - access_model
                  - apis
                relationship:
                  type: string
                  enum:
                  - provider
                  - customer
                  - observer
                  description: Never gates the report; it sets priority.
                contact:
                  type: string
                  description: Where to reply. Omitted means poll status_url instead.
            example:
              wrong: our error_semantics dimension reads false
              correct: we publish one error schema referenced across operations
              evidence: https://example.com/docs/errors
              field: score
              relationship: provider
      responses:
        '202':
          description: Queued for a person.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/claim:
    post:
      operationId: claimListing
      summary: Create or return your claim on this listing
      description: 'Ownership is proved against a host we already hold for the provider. A provider with no website on file cannot be claimed until a correction supplies one — the 422 says so rather than failing opaquely.


        IDEMPOTENT FOR YOU, CONTESTED ACROSS PARTIES. Claiming again when you already have an open claim returns that claim (`outcome: already_claimed`), not a second one. A claim on a listing ANOTHER party has already claimed is a 409 — that is a dispute a person decides, and telling you your claim was progressing when it is someone else''s would be a lie.'
      x-tier: business
      x-mcp-tool: claim_listing
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                contact:
                  type: string
      responses:
        '202':
          description: Claim queued for verification.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedRequest'
        '200':
          description: You already have an open claim on this listing. This is that claim.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpsertResult'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '409':
          description: Another party has an open claim on this listing. A person decides it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: No provable host on file, so the claim cannot be checked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/facts:
    post:
      operationId: correctFacts
      summary: Create or update your pending fact correction for this listing
      description: 'Structured corrections an operator applies by hand. Send one or more of the fields below.


        AN UPSERT, scoped to you. While you have an open correction for this provider a second call AMENDS it in place and keeps its id, so you keep polling the same status_url and an operator works one currently-correct row rather than reconciling three. `outcome` says which happened: `created` (202) or `amended` (200), with `previous` carrying what was replaced.


        Scoped to the submitter deliberately: a different person correcting the same provider files their own request, because two people disagreeing about a listing is something a human must see rather than a silent overwrite.'
      x-tier: business
      x-mcp-tool: correct_facts
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              minProperties: 1
              description: One or more of the properties below.
              properties:
                name:
                  type: string
                description:
                  type: string
                url:
                  type: string
                  format: uri
                industries:
                  type: array
                  items:
                    type: string
                tags:
                  type: array
                  items:
                    type: string
                contact:
                  type: string
      responses:
        '200':
          description: Your open correction for this provider was amended in place. Same id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpsertResult'
        '202':
          description: Filed as a new request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpsertResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/submit:
    post:
      operationId: submitArtifact
      summary: Create or update an artifact pointer for this listing
      description: 'Point us at an artifact you publish — an OpenAPI, an AsyncAPI, a rules file — and it is fetched and wired by an operator.


        UPSERT ON (type, url). Submitting a pointer we already hold — same type AND same url — is a no-op that says so (`outcome: unchanged`), and nothing is queued. Submitting a NEW url of a type we already hold is an ADDITION, not a replacement: providers legitimately publish several specs, and silently replacing one would remove an artifact you are already scored for, so a submission meant to raise a score would lower it. `existing_of_type` tells you how many we already hold.'
      x-tier: business
      x-mcp-tool: submit_artifact
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - type
              - url
              properties:
                type:
                  type: string
                  description: Artifact type
                  e.g. OpenAPI: null
                  AsyncAPI: null
                  Rules.: null
                url:
                  type: string
                  format: uri
                contact:
                  type: string
            example:
              type: OpenAPI
              url: https://example.com/openapi.yml
      responses:
        '200':
          description: We already hold that exact pointer. Nothing was queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpsertResult'
        '202':
          description: Queued as an addition.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpsertResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/visibility:
    post:
      operationId: setVisibility
      summary: Request restricted listing or removal
      description: A person applies this — it strips artifacts, pages and rollups across the network.
      x-tier: business
      x-mcp-tool: set_visibility
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - visibility
              properties:
                visibility:
                  type: string
                  enum:
                  - restricted
                  - delisted
                  description: restricted — name, description and a link to your own site, unrated and out of every ranked view. delisted — removed from the catalog entirely.
                reason:
                  type: string
                contact:
                  type: string
      responses:
        '202':
          description: Queued and prioritised.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/dispute:
    post:
      operationId: disputeFinding
      summary: Dispute something the rating says about this provider
      description: '"You say I lack X, here it is." Open to any paying caller rather than owners only: requiring a claim first would mean the people most motivated to fix a wrong score have to wait on a manual verification before they can tell us we are wrong.'
      x-tier: business
      x-mcp-tool: dispute_finding
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - claim
              properties:
                claim:
                  type: string
                evidence_url:
                  type: string
                  format: uri
                contact:
                  type: string
            example:
              claim: you say we have no OpenAPI
              evidence_url: https://example.com/openapi.yml
      responses:
        '202':
          description: Filed. A person fetches your evidence and emails you either way.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /providers/{slug}/generate:
    post:
      operationId: generateArtifacts
      summary: What APIs.io can generate on this provider's behalf
      description: Reports which artifacts we can author for this provider and how to ask for them. Read-only despite the verb.
      x-tier: business
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      responses:
        '200':
          description: What is available.
          content:
            application/json:
              schema:
                type: object
                properties:
                  slug:
                    type: string
                  name:
                    type: string
                  available:
                    type: array
                    items:
                      type: string
                  usage:
                    type: string
        '402':
          $ref: '#/components/responses/UpgradeRequired'
  /providers/{slug}/projection:
    post:
      operationId: simulateFixes
      summary: What a set of fixes would move the score to
      description: A dry run. Nothing is stored and nothing is queued — the verb is POST because the fix list is a body, not because this writes.
      x-tier: business
      x-mcp-tool: simulate_fixes
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - fixes
              properties:
                fixes:
                  type: array
                  items:
                    type: string
                  description: Check or dimension ids
                  as returned by /remediation.: null
            example:
              fixes:
              - error_semantics
      responses:
        '200':
          description: The projected score, and which fixes were rejected as unmodellable.
          content:
            application/json:
              schema:
                type: object
                properties:
                  slug:
                    type: string
                  applied:
                    type: array
                    items:
                      type: string
                  rejected:
                    type: array
                    items:
                      type: string
                  from:
                    type: number
                  to:
                    type: number
                  score_gain:
                    type: number
                  band_changed:
                    type: boolean
                  model_drift:
                    type: string
                  model_drift_note:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
  /providers/{slug}/remediation:
    get:
      operationId: whatCanIFix
      summary: The ranked, costed punch list for this provider
      description: One ordered list across both rating layers. `do_first` prefers a band gate over any amount of points, because points cannot clear a gate.
      x-tier: business
      x-mcp-tool: what_can_i_fix
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      responses:
        '200':
          description: Ranked items, gates, and the headline.
          content:
            application/json:
              schema:
                type: object
                properties:
                  slug:
                    type: string
                  current:
                    type: object
                  do_first:
                    type: object
                  gates:
                    type: object
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        kind:
                          type: string
                          enum:
                          - check
                          - facet
                          description: A named check
                          or a facet rollup where no check data explains that facet.: null
                        layer:
                          type: string
                          enum:
                          - kin_score
                          - agent_readiness
                        id:
                          type: string
                        score_gain:
                          type: number
                          description: Composite points
                          not raw rubric points.: null
                        what_satisfies_it:
                          type: string
        '402':
          $ref: '#/components/responses/UpgradeRequired'
  /providers/{slug}/gates:
    get:
      operationId: readinessGates
      summary: Band gates for this provider, and what is unmet
      x-tier: business
      x-mcp-tool: readiness_gates
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      responses:
        '200':
          description: Current band, the next band, and every gate requirement with its status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadinessGates'
        '402':
          $ref: '#/components/responses/UpgradeRequired'
  /providers/{slug}/rating/checks:
    get:
      operationId: providerRatingChecks
      summary: Per-check Kin Score results for this provider
      description: Actionable checks only — missed and partial. `counts` reports all four statuses so a reader can verify nothing is hidden. Ordered by points available.
      x-tier: business
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      parameters:
      - $ref: '#/components/parameters/Slug'
      responses:
        '200':
          description: The per-check results, joined against the rubric.
          content:
            application/json:
              schema:
                type: object
                properties:
                  slug:
                    type: string
                  scored_at:
                    type: string
                  rubric_version:
                    type: string
                  counts:
                    type: object
                  checks:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        status:
                          type: string
                          enum:
                          - missed
                          - partial
                        label:
                          type: string
                        facet:
                          type: string
                        points_available:
                          type: number
                        what_satisfies_it:
                          type: string
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '404':
          $ref: '#/components/responses/NotFound'
        '503':
          description: Per-check results are not loaded for this build. A gap in our data, not a statement that you failed nothing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /checks:
    post:
      operationId: requestCheck
      summary: Ask for a provider, industry, tag or area to be re-profiled
      description: A check means re-running the enrichment pipeline against a live surface — a human-supervised job. The request takes a place in a queue rather than returning an answer.
      x-tier: business
      x-mcp-tool: request_check
      tags:
      - Provider Control
      security:
      - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                slug:
                  type: string
                url:
                  type: string
                  format: uri
                targetType:
                  type: string
                  enum:
                  - provider
                  - industry
                  - tag
                  - area
                  - estate
                  - catalog
                kind:
                  type: string
                notes:
                  type: string
                contact:
                  type: string
      responses:
        '200':
          description: Queued.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  queued:
                    type: boolean
                  detail:
                    type: string
        '402':
          $ref: '#/components/responses/UpgradeRequired'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
  /gaps/report:
    post:
      operationId: reportGap
      summary: Tell us what you looked for and did not find
      description: Keyless and free on purpose — a gap report that must be paid for is a report we do not get.
      x-tier: free
      x-mcp-tool: report_gap
      tags:
      - Provider Control
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - looked_for
              properties:
                looked_for:
                  type: string
                context:
                  type: string
                contact:
                  type: string
      responses:
        '202':
          description: Received.
          content:
            application/json:
              schema:
                type: object
                properties:
                  received:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '503':
          $ref: '#/components/responses/QueueUnreachable'
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        detail:
          type: string
    QueuedRequest:
      type: object
      description: Every write here is a REQUEST, not a completed action. `completed` is always false on acceptance.
      properties:
        received:
          type: boolean
        completed:
          type: boolean
        request_type:
          type: string
        slug:
          type: string
        id:
          type: string
          description: Poll status_url with this.
        status:
          type: string
        status_url:
          type: string
        detail:
          type: string
    UpsertResult:
      type: object
      description: A write whose repeat behaviour is defined. `outcome` names which branch ran, so a caller retrying after a timeout can tell what the server did without re-reading the record.
      allOf:
      - $ref: '#/components/schemas/QueuedRequest'
      - type: object
        properties:
          outcome:
            type: string
            enum:
            - created
            - amended
            - unchanged
            - already_claimed
            description: created — a new request. amended — your open one was replaced, same id. unchanged — we already hold this, nothing queued. already_claimed — your existing claim, not a second.
          previous:
            type: object
            description: On an amend
            what the request held before.: null
          revisions:
            type: integer
            description: How many times this request has been amended.
          existing_of_type:
            type: integer
            description: On submit
            how many pointers of this type we already hold.: null
    BandGate:
      type: object
      description: One band's score floor and the gate guarding it.
      properties:
        band:
          type: string
          enum:
          - agent-native
          - agent-ready
          - agent-aware
          - human-only
          maxLength: 1024
        label:
          type: string
          maxLength: 256
        min:
          type: number
          description: Score floor for this band.
        points_short:
          type: integer
          description: Points still needed to reach the floor. 0 once the floor is met.
        gated:
          type: boolean
          description: Whether this band carries a gate at all.
        gate_requires:
          type: array
          description: Dimensions the gate requires.
          items:
            type: string
            maxLength: 128
        gate_met:
          type: array
          description: Required dimensions this provider satisfies.
          items:
            type: string
            maxLength: 128
        gate_unmet:
          type: array
          description: Required dimensions still missing. Empty when the gate is satisfied.
          items:
            type: string
            maxLength: 128
        gate_satisfied:
          type: boolean
        demote_to:
          type: string
          description: Band a provider falls to when the gate is not satisfied.
          maxLength: 128
        blocking:
          type: array
          description: What is actually holding this provider out of the band — the score, the gate, or both.
          items:
            type: string
            maxLength: 256
        rationale:
          type: string
          description: Why this band is gated the way it is.
          maxLength: 4096
      additionalProperties: true
    ReadinessGates:
      type: object
      description: What stands between this listing and the next agent-readiness band. Agent Readiness is additive, so a provider can reach a band's score floor and still be held below it by the band GATE — this says which, and what would satisfy it.
      required:
      - slug
      - name
      - current_band
      - current_score
      properties:
        slug:
          type: string
          maxLength: 128
        name:
          type: string
          maxLength: 256
        current_score:
          type: number
          minimum: 0
          maximum: 100
        current_band:
          type: string
          enum:
          - agent-native
          - agent-ready
          - agent-aware
          - human-only
          maxLength: 1024
        band_gated_from:
          type: string
          description: The band this provider SCORED into but was demoted from by the gate. Absent when no demotion applied — a provider held at its scored band was not gated.
          enum:
          - agent-native
          - agent-ready
          - agent-aware
          - human-only
          maxLength: 1024
        verdict:
          type: string
          description: One line saying where the provider stands and why.
          maxLength: 2048
        next_band:
          $ref: '#/components/schemas/BandGate'
        all_bands:
          type: array
          description: Every band with its floor and gate, so the whole ladder is visible at once.
          items:
            $ref: '#/components/schemas/BandGate'
      additionalProperties: true
  responses:
    QueueUnreachable:
      description: The request queue is not reachable. The response says where else to reach us — a request here is never dropped silently.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: The body did not carry what this operation needs. The response names the fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: No such provider, or nothing stored for it.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    UpgradeRequired:
      description: A valid credential below the required plan. An unauthenticated caller gets 401 with a bootstrap challenge instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  parameters:
    Slug:
      name: slug
      in: path
      required: true
      description: The provider slug the record is filed under.
      schema:
        type: string
      example: apis-io
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key