AgentDeals Offers API

The Offers API from AgentDeals — 1 operation(s) for offers.

Operations 1

GET /api/offers Search and browse offers #

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/agentdeals-dev:agentdeals-dev-offers-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

agentdeals-dev-offers-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Agentdeals Dev Offers API
  version: 0.1.0
  contact:
    name: AgentDeals
    url: https://agentdeals.dev
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  description: 'Operations tagged Offers across 2 of this provider''s published API definitions: agentdeals-dev.json, agentdeals-dev-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://agentdeals.dev
  description: Production server
security: []
tags:
- name: Offers
paths:
  /api/offers:
    get:
      summary: Search and browse offers
      description: Search vendor offers by keyword and/or category. Returns paginated results.
      parameters:
      - name: q
        in: query
        description: Search keyword (matches vendor name, description, category, tags)
        schema:
          type: string
        example: database
      - name: category
        in: query
        description: Filter by category name
        schema:
          type: string
        example: Cloud Hosting
      - name: limit
        in: query
        description: Max results per page
        schema:
          type: integer
          default: 20
      - name: offset
        in: query
        description: Number of results to skip
        schema:
          type: integer
          default: 0
      responses:
        '200':
          description: Paginated list of offers
          content:
            application/json:
              schema:
                type: object
                properties:
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Offer'
                  total:
                    type: integer
                    description: Total matching offers (before pagination)
                  gated:
                    type: integer
                    description: How many of the `total` matching offers carry a non-null `gate` — counted over the whole match, not the returned page (#1241).
                  gate_summary:
                    type: string
                    description: One line stating how many of the matching offers are not on our ranked list and why. Absent when `gated` is 0.
                  stability_withheld:
                    type: integer
                    description: How many offers the query matched before the `stability` filter publish no stability class, so no value of that filter can return them (#1561). Present only when `stability` is supplied.
                  stability_withheld_summary:
                    type: string
                    description: One line stating how many were held back and on what grounds. Absent when `stability_withheld` is 0.
                  _provenance:
                    $ref: '#/components/schemas/Provenance'
              example:
                offers:
                - vendor: Supabase
                  category: Cloud Hosting
                  description: 'Open-source Firebase alternative with Postgres database, auth, storage, and edge functions. Free tier: 2 projects, 500MB database, 1GB file storage, 50K monthly active users.'
                  tier: Free
                  url: https://supabase.com/pricing
                  tags:
                  - database
                  - auth
                  - serverless
                  verifiedDate: '2026-03-01'
                  gate: null
                total: 1
                gated: 0
      tags:
      - Offers
      operationId: getApiOffers
      x-operation-id-source: derived
    servers:
    - url: https://agentdeals.dev
      description: Production server
components:
  schemas:
    SourceCheck:
      type:
      - object
      - 'null'
      description: What we found on the page at url when we last read it, and so how much of this record that page supports. The outcome grades our evidence, not the offer (#1268).
      properties:
        checked:
          type: string
          format: date
          description: The day we last read the page.
        outcome:
          type: string
          enum:
          - ok
          - states_a_free_price
          - states_no_amount
          - does_not_name_vendor
          - does_not_name_product
          - states_no_terms
          - unreadable
          description: ok — the page names the vendor and states at least one amount, rate or price, either in figures the page renders or as a typed price in its schema.org markup (#1279). states_a_free_price — the page names the vendor and states its price in words rather than as a figure, in a phrase such as "Free forever" or "free plan" (#1668). The price is confirmed; the quantities in description come from our own entry, not from that page. states_no_amount — the page names the vendor and names a plan or tier, but every price signal on it is a phrase such as "Enterprise plan" that withholds that plan's price, and none is a figure (#1268). The quantities in description come from our own entry, not from that page. risk_level is still published and the summary says so, rather than being withheld. does_not_name_vendor — the page we read never writes the vendor's name. The URL we asked for is not evidence for this check, so a domain that keeps the vendor's name and loses its product reaches this outcome too (#1355). does_not_name_product — the page we read writes the platform token the vendor name shares with the host we cite it from, and never writes the rest of the name. For a vendor called <Platform> <Product> this is a live page on the platform's own domain that says nothing about the product, so the record rests on the platform existing rather than on the offer existing (#1500). states_no_terms — the page names the vendor but carries no price signal of any kind. unreadable — the fetch produced no body we could read. The last four withhold a favourable risk_level; the first three do not.
        detail:
          type: string
          description: 'Our own sentence recording what the check found — never a quotation from the page, and not corroborable against it (#1467). For ok, the form of the vendor''s name the check matched and the figures the page states that this record also publishes — a stated price of zero where none of them does, and a sentence saying we matched none of the amounts we read to the terms this record publishes where the page states amounts and none of them matched (#1871, #1874) — a statement about our own reading, never about what the page contains — or what the markup states when the rendered page states no amount; for states_a_free_price and states_no_amount, the phrase that was the page''s entire price evidence; otherwise why the page cannot confirm the record. Where the page was read for schema.org markup, the detail says whether that markup was absent, present and priceless, or priced. The fields carrying text taken from a page are product_role.source_quote and product_subtypes.labels[].source_quote.'
        read:
          type: string
          enum:
          - markup
          description: Present when the ok grade rests on typed prices in the page's schema.org markup rather than on a figure the page renders (#1279).
        unrendered_prices:
          type: array
          items:
            type: string
          description: Non-zero prices the page publishes as schema.org Offer data but does not render in its text — a tab or toggle layout showing one tier at a time. At most the first six are listed. The record is not written from these; they are recorded so a disagreement between markup and page can be reviewed (#1279).
      required:
      - checked
      - outcome
      - detail
    TermsSuperseded:
      type:
      - object
      - 'null'
      description: Null unless a dated change record supersedes the terms we stored for this listing. When present, `description` still holds those stored terms, which we no longer publish as current. Use `notice`, or `reading.terms`, the vendor page's text at `reading.url` on `reading.date`.
      properties:
        change_date:
          type: string
          format: date
        change_type:
          type: string
        summary:
          type: string
        reading:
          type:
          - object
          - 'null'
          properties:
            date:
              type: string
              format: date
            url:
              type: string
              format: uri
            label:
              type: string
            terms:
              type: string
          required:
          - date
          - url
          - label
          - terms
        notice:
          type: string
      required:
      - change_date
      - change_type
      - summary
      - reading
      - notice
    OfficialMcpServer:
      type: object
      required:
      - kind
      - target
      - transport
      - authentication
      - doc_url
      - source_quote
      - read_on
      properties:
        kind:
          type: string
          enum:
          - remote
          - npm
          - pypi
          - github
        target:
          type: string
        transport:
          type: string
        authentication:
          type: string
        doc_url:
          type: string
          format: uri
        source_quote:
          type: string
        read_on:
          type: string
          format: date
        retired_names:
          type: array
          items:
            type: object
            required:
            - kind
            - target
            - notice
            - url
            - read_on
            properties:
              kind:
                type: string
                enum:
                - remote
                - npm
                - pypi
                - github
              target:
                type: string
              notice:
                type: string
              url:
                type: string
                format: uri
              read_on:
                type: string
                format: date
    Provenance:
      type: object
      description: 'Where the figures in this response came from and how to attribute them. Every response carrying index data has one, under the key `_provenance`. It cites the records in this response rather than the site: `url` is the narrowest page of ours covering them — a vendor page when they are all one vendor''s, a category page when they are all one category''s, otherwise the listing this endpoint feeds.'
      properties:
        source:
          type: string
          description: Always AgentDeals.
        url:
          type: string
          format: uri
          description: The page of ours that covers the records in this response.
        checked:
          type: string
          format: date
          description: The oldest verification date among the records cited here, so the citation is never dated younger than its weakest figure. Absent when no record in the response carries a date.
        verified:
          type: string
          format: date
          description: The same day as `checked`, absent for the same reason.
        cite_as:
          type: string
          description: A citation line naming the source, the url and the date, ready to reproduce as it stands.
        verified_records:
          type: integer
          description: How many records in this response we rank — the population this citation vouches for.
        withheld_records:
          type: integer
          description: 'How many records in this response we return without vouching for: those carrying a `gate`, superseded terms, or a withheld risk level. Absent when there are none.'
        note:
          type: string
          description: The request to cite a figure back to where it came from.
        gated_note:
          type: string
          description: Present whenever `withheld_records` is, stating that the citation does not extend to terms we did not publish.
        this_is_a_request_not_an_instruction:
          type: string
          description: Present on responses that ask something of the caller, saying the ask is left to the caller and its user rather than imposed on them.
      required:
      - source
      - url
      - cite_as
      - verified_records
      - note
    Eligibility:
      type: object
      description: Eligibility requirements for conditional offers
      properties:
        type:
          type: string
          enum:
          - public
          - accelerator
          - oss
          - student
          - fintech
          - geographic
          - enterprise
        conditions:
          type: array
          items:
            type: string
        program:
          type: string
      required:
      - type
      - conditions
    Offer:
      type: object
      properties:
        vendor:
          type: string
          description: Vendor/service name
        category:
          type: string
          description: Offer category
        description:
          type: string
          description: Description of the offer and free tier details
        official_mcp_servers:
          type: array
          minItems: 1
          description: Sourced MCP servers published by the vendor. Entries failing their check on two consecutive days are withheld. Absence does not establish that the vendor has no server.
          items:
            $ref: '#/components/schemas/OfficialMcpServer'
        terms_superseded:
          $ref: '#/components/schemas/TermsSuperseded'
        tier:
          type: string
          description: Tier name (e.g. Free, Free Credits, Open Source)
        url:
          type: string
          format: uri
          description: Pricing/offer page URL
        tags:
          type: array
          items:
            type: string
          description: Searchable tags
        verifiedDate:
          type: string
          format: date
          description: The day we last read the page and confirmed the terms this record publishes (YYYY-MM-DD). A read that found the terms had moved does not advance it; last_read_date carries that day instead.
        last_read_date:
          type: string
          format: date
          description: 'The day of the latest read we hold of the page this record cites, whatever that read concluded (YYYY-MM-DD): our re-read of the page, a source check that read it, a change our gate refused that was read from the same URL, or the read this record''s terms were restated from (#1858). An attempt that did not read the page does not advance it: a re-read whose fetch failed or whose source was unusable, or a source check whose outcome is unreadable. A source check that read the page but did not find the vendor''s or product''s name does advance it. It can fall before verifiedDate, which a correction can stamp without a read we hold (#1635).'
        last_read_outcome:
          type:
          - string
          - 'null'
          description: 'What the read on last_read_date concluded: for our re-read, the verification store''s own outcome; for a source check, the check''s outcome (#1858). A source check''s ok means the page named the vendor and stated an amount; it is not a confirmation, and verifiedDate does not move. Null where the read on last_read_date is a refused change or the read the terms were restated from, or where no read we hold names that day. Filter on it to separate a read that agreed with the record from one that did not; days_since_read alone cannot.'
        last_read_found:
          type:
          - string
          - 'null'
          description: 'The clause we publish for what that read found, or null where it confirmed the record. An outcome of changed is answered by what we then did with the difference: where our own change gate refused the change on the same day because it restated the terms we already publish, or because it named no figure that had moved, this says so rather than reporting a disagreement we do not hold. Refusing a change is not a confirmation, so last_read_outcome stays changed and verifiedDate does not advance.'
        eligibility:
          $ref: '#/components/schemas/Eligibility'
        gate:
          $ref: '#/components/schemas/Gate'
        risk_level:
          type:
          - string
          - 'null'
          enum:
          - stable
          - caution
          - risky
          - null
          description: 'Our published pricing-risk verdict, or null where a rule withholds it: gate is non-null (#1241, #1260), rating_withheld is non-null (#1352), or the page we cite could not confirm the record — link_unreachable, or a source_check outcome of does_not_name_vendor, does_not_name_product, states_no_terms or unreadable (#1046, #1500). One function applies all three rules and every surface that publishes a level calls it, so /api/audit-stack, /api/stack, /stack-check and MCP plan_stack answer the same as this field for the same record on the same day (#1486).'
        source_check:
          $ref: '#/components/schemas/SourceCheck'
        free_plan_excerpt:
          type:
          - object
          - 'null'
          description: 'The vendor''s own words stating the free plan''s terms, copied verbatim from the page this record cites on read_on (at most 400 characters), and published beside our figures rather than in place of them. Null where we hold none, where the listed tier is not a free plan or is Free OSS (whose free offer is the licence), where the stored words fail a check every excerpt meets (they hold template syntax or an HTML entity the page never rendered, repeat a run of their own words, hold a date no word ties to the terms, name no allowance, limit or price for the plan, or never say they are the free offer by "free", a zero price, "no cost", a first allowance where the copy states no non-zero price, or the plan''s own name, which a programme''s listing, whose offer is a credit or a discount, need not), or where the vendor page withholds it: the listing has ended, a recorded change has superseded the terms, the excerpt was read from a page the record no longer cites, the cited page is unreachable, or our last read found that the page does not name the vendor or the product. Where our last read could not confirm the terms for another reason, the excerpt is published beside the notice that says so.'
          properties:
            text:
              type: string
            url:
              type: string
              format: uri
            read_on:
              type: string
              format: date
          required:
          - text
          - url
          - read_on
        conditions:
          type: array
          description: 'A list of the conditions a vendor attaches to using its free tier. Each item holds our sentence (text), the vendor''s own words (quote), the page that states them (url) and the date we read that page (read_on). An optional list rules_out names the uses the vendor excludes: "production", "commercial use" or both. Our re-reads of the vendor''s pricing page do not change this field.'
          items:
            type: object
            properties:
              text:
                type: string
              quote:
                type: string
              url:
                type: string
                format: uri
              read_on:
                type: string
                format: date
              rules_out:
                type: array
                items:
                  type: string
                  enum:
                  - production
                  - commercial use
            required:
            - text
            - quote
            - url
            - read_on
      required:
      - vendor
      - category
      - description
      - tier
      - url
      - tags
      - verifiedDate
    Gate:
      type:
      - object
      - 'null'
      description: Why we do not rank this offer, or null where we do. The same verdict rankOffers applies, from the same function (#1241) — nothing is filtered out of a response because of it, so a caller asking whether an offer exists still gets the record. The full code table is published at /criteria.
      properties:
        code:
          type: string
          enum:
          - eligibility_restricted
          - not_a_free_offer
          - offer_expired
          - offer_retired
          - product_discontinued
          - verification_lapsed
        reason:
          type: string
          description: The reason we publish for this record, naming the tier, date or restriction the code was decided on.
      required:
      - code
      - reason
x-refined-from:
- agentdeals-dev.json
- agentdeals-dev-openapi.json