Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Agentdeals Dev New API
version: 0.1.0
contact:
name: AgentDeals
url: https://agentdeals.dev
license:
name: MIT
url: https://opensource.org/licenses/MIT
description: 'Operations tagged New 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: New
paths:
/api/new:
get:
summary: Recently added or updated offers
description: Returns offers where verifiedDate falls within the last N days.
parameters:
- name: days
in: query
description: Number of days to look back (1-30)
schema:
type: integer
default: 7
example: 7
- name: limit
in: query
description: Max results to return
schema:
type: integer
default: 50
responses:
'200':
description: List of offers by catalogue date, newest first
content:
application/json:
schema:
type: object
properties:
offers:
type: array
items:
$ref: '#/components/schemas/Offer'
total:
type: integer
_provenance:
$ref: '#/components/schemas/Provenance'
tags:
- New
operationId: getApiNew
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