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/medianfi-com:medianfi-com-public-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: 3.2.0
info:
title: Median Public API
version: 0.1.0
description: Production-grade Node.js + Express API starter template
license:
name: Proprietary
servers:
- url: /api/v1
security: []
tags:
- name: Public
paths:
/public/invoices/{token}:
parameters:
- name: token
in: path
required: true
description: 'The 192-bit URL-safe payment token minted at invoice send. It is the SOLE capability handle — these routes are unauthenticated and not company-scoped by URL; the server derives the company scope and dark gate from the token.
'
schema:
type: string
get:
operationId: getPublicInvoiceByToken
summary: Public pay-page view for an invoice payment token (unauthenticated)
description: 'AR charge rail (Stage 2). UNAUTHENTICATED; rate-limited per-IP and per-token. Resolves the token to the pay-page view: { merchant: { name, supportEmail? }, invoice: { number, issueDate, dueDate, terms, currency, subtotalCents, taxCents, totalCents, amountPaidCents, amountDueCents, status: open|partially_paid|paid, lines }, methods: { card: { available, feeMode, feeCents, amountToChargeCents }, bankTransfer: { available, details } } }. bankTransfer.details is the FULL (unmasked) structured bank block — the payer needs it to push an ACH/wire — and is non-null only when bank transfer is enabled AND the payer-required fields (holder, bank, routing, account) are all present. UNIFORM-404 SEMANTICS: an unknown/blank token, a draft/void/uncollectible invoice, a closed AR/AP surface, or a non-allowlisted/non-active company ALL return the same 404 shape so the endpoint never leaks whether a token, company, or invoice exists.'
tags:
- Public
security: []
responses:
'200':
description: PublicInvoiceView (see description for shape)
'404':
description: Uniform not-found — identical for every rejection branch (no enumeration oracle)
'429':
description: Rate limited (per-IP or per-token)
/public/invoices/{token}/payment-intent:
parameters:
- name: token
in: path
required: true
schema:
type: string
post:
operationId: createPublicInvoicePaymentIntent
summary: Create a TEST-mode Stripe PaymentIntent for the invoice (unauthenticated)
description: 'AR charge rail (Stage 3 — TEST MODE ONLY). UNAUTHENTICATED; rate-limited per-IP and per-token. The request body is EMPTY and ignored: the amount is SERVER-authoritative (outstanding = amount − paid; force-absorb means the payer is charged the principal only), and no caller-supplied field reaches the intent — the idempotency key is a pure function of (token, outstanding), so one pay link yields at most ONE PaymentIntent. (The payer''s card receipt is set browser-side at confirm time via Stripe''s `receipt_email`.) Returns { clientSecret, publishableKey (TEST), connectedAccountId, amountChargedCents } for Stripe.js; the card is tokenized in-browser and PAN/CVC never reach this API. Marks nothing paid — settlement is the signature-verified Stage-4 webhook. Same uniform-404 token gate as the GET.'
tags:
- Public
security: []
responses:
'200':
description: '{ clientSecret, publishableKey, connectedAccountId, amountChargedCents }'
'404':
description: Uniform not-found (same semantics as GET)
'409':
description: INVOICE_NOT_PAYABLE — already paid or no outstanding balance
'422':
description: STRIPE_ACCOUNT_CANNOT_CHARGE — card rail unavailable (disabled toggle or the connected account cannot charge right now)
'429':
description: Rate limited (per-IP or per-token)
'503':
description: Card charging is not configured on this deployment
/public/invoices/{token}/bank-transfer-initiated:
parameters:
- name: token
in: path
required: true
schema:
type: string
post:
operationId: acknowledgePublicInvoiceBankTransfer
summary: Payer soft signal that a bank transfer was sent (unauthenticated)
description: AR charge rail (Stage 5). UNAUTHENTICATED; rate-limited per-IP and per-token. Records ONE durable ach/pending invoice_payments row (amount = outstanding at signal time; repeated clicks are a no-op) so the merchant can see the claim. It NEVER marks the invoice paid and NEVER changes lifecycle status — the merchant reconciles the real deposit. The response is identical whether or not a row was written. Same uniform-404 token gate as the GET.
tags:
- Public
security: []
responses:
'200':
description: '{ acknowledged: true }'
'404':
description: Uniform not-found (same semantics as GET)
'429':
description: Rate limited (per-IP or per-token)
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
serviceApiKey:
type: apiKey
in: header
name: X-API-Key
description: 'Persistent credential for the configured cloud-bookkeeping service principal. The key must carry accountant:* and is accepted only on accountant operations that explicitly list this scheme. Ordinary API keys, and service keys presented to bearer-only operations, are denied.
'
refreshSessionCookie:
type: apiKey
in: cookie
name: __Secure-median_refresh
description: 'Exact production HttpOnly refresh-session cookie. Local non-secure development uses median_refresh.
'
passkeyEnrollmentGrantCookie:
type: apiKey
in: cookie
name: __Secure-median_passkey_enrollment
description: 'Exact production HttpOnly passkey-enrollment grant cookie. Local non-secure development uses median_passkey_enrollment.
'
webAuthnCeremonyCookie:
type: apiKey
in: cookie
name: __Secure-median_webauthn
description: 'Exact production HttpOnly WebAuthn ceremony cookie. Local non-secure development uses median_webauthn.
'
x-median-quarantined-authorities:
decision: ADR-0001-model-a
runtimeStatus: unmounted
description: 'Migrations 267-272 modeled legal entities as separate company tenants. These paths are not runtime API authority while their preserved accounting math is re-keyed to legal entities inside one company workspace.
'
paths:
- /companies/{companyId}/consolidation-groups
- /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/report-rollups
- /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/report-rollups/{rollupId}
- /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/translation-adjustments
- /companies/{companyId}/consolidation-groups/{groupId}/versions/{groupVersionId}/translation-adjustments/{adjustmentId}
x-median-demo-parity-customer-surface:
runtimeStatus: mounted-lifecycle-only
description: 'v2 customer-app capabilities available to JWT-authenticated members of any active or test company — the v2 app is the product, not a rollout cohort, so no allowlist applies to the markerless path. Production customer calls omit X-Median-App-Surface. Test-company calls may carry X-Median-App-Surface: qa to select the QA bundle; that marker branch alone still requires membership in CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS. An API key, unknown marker, malformed company id, inactive company, missing gate dependency, or failed company lookup receives the standard hidden-resource 404 contract. The held surfaces riding these prefixes (AR/AP, Forecast, Insights) carry their own additional allowlist gate — see x-median-forecast-hold and x-median-ar-ap-hold.
'
headerContract: '#/components/parameters/demoParityCustomerAppSurface'
routePrefixes:
- /companies/{companyId}/ar
- /companies/{companyId}/ap
- /companies/{companyId}/customers
- /companies/{companyId}/vendors
- /companies/{companyId}/contracts
- /companies/{companyId}/receivables
- /companies/{companyId}/entities
- /companies/{companyId}/currencies
- /companies/{companyId}/reporting-scopes
- /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/rollups
- /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/translation-adjustments
- /companies/{companyId}/presentation-report-snapshots
- /companies/{companyId}/reporting-trial-balances
- /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/trial-balances
- /companies/{companyId}/reporting-scopes/{reportingScopeId}/versions/{versionId}/intercompany
- /companies/{companyId}/weekly-email
- /companies/{companyId}/forecast
- /companies/{companyId}/books
- /companies/{companyId}/sub-ledgers
x-median-forecast-hold:
runtimeStatus: mounted-only-with-server-gate
description: 'Forecast is held. Beyond the lifecycle-only customer surface above, every operation under the prefix below also requires the company to appear in the held-surface allowlist CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS — the one operator-set list that opens AR/AP, Forecast and Insights (the legacy CUSTOMER_APP_FORECAST_COMPANY_IDS variable is no longer consulted). It is empty by default, so the v2 rollout alone never exposes Forecast. A company off the list receives the same hidden-resource 404 contract as one for which the surface does not exist. The auth-context featureFlags key `forecast` mirrors this verdict for the customer app shell.
'
featureFlag: forecast
routePrefixes:
- /companies/{companyId}/forecast
x-median-ar-ap-hold:
runtimeStatus: mounted-only-with-server-gate
description: 'Receivables/Payables are held behind TWO required authorities. Beyond the lifecycle-only customer surface above, every operation under the prefixes below requires the company to appear in the held-surface allowlist CUSTOMER_APP_DEMO_PARITY_COMPANY_IDS (requireDemoParityAllowlistedCompany) AND to satisfy the company_subledger_flags conversion chain (requireArApItemsEnabled — the same authority the public /pay page, aging and the accountant portal consult); failing either answers the opaque 404. The auth-context featureFlags key `arApItems` mirrors exactly that conjunction, resolved server-side, so the customer shell hides the Receivables/Payables nav and pages instead of offering menu entries these routes 404. Default is FALSE for every company while the list is empty or the conversion has not run.
'
featureFlag: arApItems
routePrefixes:
- /companies/{companyId}/ar
- /companies/{companyId}/ap
- /companies/{companyId}/customers
- /companies/{companyId}/vendors
- /companies/{companyId}/contracts
- /companies/{companyId}/receivables
x-median-demo-parity-qa-only:
runtimeStatus: mounted-only-with-server-gate
description: 'Strict test-company-only routes. Every interactive call requires X-Median-App-Surface: qa in addition to JWT authentication, the server allowlist, and persisted client_status=test. A copied header, API key, active company, missing gate dependency, or failed company lookup receives the standard hidden-resource 404 contract.
'
headerContract: '#/components/parameters/qaAppSurface'
routePrefixes:
- /companies/{companyId}/gl-accounts/{id}/monetary-classification
- /companies/{companyId}/fx-account-roles
- /companies/{companyId}/gl-periods/{periodId}/fx-revaluation
- /accountant/companies/{customerId}/gl-accounts/{id}/monetary-classification
- /accountant/companies/{customerId}/fx-account-roles
- /accountant/companies/{customerId}/gl-periods/{periodId}/fx-revaluation
- /accountant/companies/{customerId}/ar/{id}
- /accountant/companies/{customerId}/ap/{id}
x-median-onboarding-v3-surface:
runtimeStatus: promoted
promotionFlag: ONBOARDING_V3_QA_ONLY=false
description: 'Promoted. The deployment this contract describes runs ONBOARDING_V3_QA_ONLY=false, so none of the onboarding-v3 auth, pricing, or setup paths below requires X-Median-App-Surface: qa. An unmarked request is served and reaches ordinary authentication, so an unauthenticated call now answers 401 rather than the hidden-resource 404. Mounting is still conditional: with ONBOARDING_V3_ENABLED false every path below returns the hidden-resource 404 before body parsing or authentication. The header stays defined and is still honoured, because a deployment left at ONBOARDING_V3_QA_ONLY=true keeps requiring it on every path below and 404s unmarked traffic; setting that flag back to true is the rollback. On either setting the header is a pre-company bundle marker, never tenant authorization.
'
headerContract: '#/components/parameters/onboardingV3QaSurface'
routePaths:
- /auth/otp/start
- /auth/otp/verify
- /auth/passkeys/register/options
- /auth/passkeys/register/verify
- /auth/passkeys/assert/options
- /auth/passkeys/assert/verify
- /onboarding/v3/quote
- /onboarding/v3/offer/resolve
- /onboarding/v3/flow
- /onboarding/v3/setup-intent
- /onboarding/v3/subscribe
- /onboarding/v3/test-account-activation
- /onboarding/v3/checkout-session
- /onboarding/v3/checkout-session/complete
- /onboarding/v3/setup-state
- /onboarding/v3/delegate-invites
- /onboarding/v3/delegate-invites/{inviteId}
- /onboarding/v3/delegate/resolve
- /onboarding/v3/delegate
- /onboarding/v3/task-context
- /onboarding/v3/delegate/task-context
- /onboarding/v3/banks/plaid/link-token
- /onboarding/v3/banks/plaid/exchange
- /onboarding/v3/banks/commit
- /onboarding/v3/documents/google-workspace/auth-url
- /onboarding/v3/documents/google-workspace/callback
- /onboarding/v3/books/quickbooks/auth-url
- /onboarding/v3/books/quickbooks/callback
- /onboarding/v3/books/xero/auth-url
- /onboarding/v3/books/xero/callback
- /onboarding/v3/welcome-call
- /onboarding/v3/welcome-call/embed
- /onboarding/v3/books-progress
- /onboarding/v3/books/open
- /companies/{companyId}/onboarding/v3/questions
- /companies/{companyId}/onboarding/v3/questions/{questionId}/answer
- /companies/{companyId}/onboarding/v3/review-items