Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Jid Qualify API
version: 1.3.0
summary: The trust API for AI agents.
description: 'Before an agent pays, signs, books, hires or buys, Jid checks the business it is dealing with: real, active, licensed for this activity, not sanctioned, with the receipts. Every fact is cited to the registry that issued it. Decisions apply the published rules (https://jid.com/decision-rules, version 2026-10-15.1) and are not legal advice. No key: 10 requests a minute and 100 a day per IP. A free key (no card) includes 1,000 checks a month. Business information only; not a consumer report and not for FCRA purposes.'
termsOfService: https://jid.com/api-terms
contact:
name: Jid
email: hello@jid.com
url: https://jid.com
servers:
- url: https://jid.com
security:
- {}
- bearer: []
tags:
- name: qualify
description: B2B lead and counterparty qualification
paths:
/v1/outcomes:
post:
tags:
- qualify
operationId: recordOutcome
summary: Record what you decided about a screen or qualify result
description: 'With the API key that ran the result: { result_id, outcome, note? }. Or { token } from a signed outcome link. Free. Stored without personal data for 13 months; outcomes tune the published rules.'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
result_id:
type: string
outcome:
type: string
enum:
- legit
- sales_pitch
- spam
- scam
- closed
- good
- junk
- no_response
description: legit, sales_pitch, spam and scam on a qualification are also community reports (jid.com/privacy section 2b).
note:
type: string
maxLength: 280
token:
type: string
responses:
'200':
description: Recorded
content:
application/json:
schema:
type: object
properties:
result_id:
type: string
outcome:
type: string
recorded_at:
type: string
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
'404':
$ref: '#/components/responses/Error'
'410':
$ref: '#/components/responses/Error'
/v1/results:
get:
tags:
- qualify
operationId: getResults
summary: The read, checks and latest outcome of qualifications this key ran
security:
- bearer: []
parameters:
- name: ids
in: query
required: true
schema:
type: string
description: Comma-separated qual_ ids, up to 200
responses:
'200':
description: Results
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
type: object
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
/v1/qualify:
post:
tags:
- qualify
operationId: qualifyCounterparty
summary: Qualify a business lead or counterparty from a form submission or outreach
description: 'API key required; counts as 2 checks. Checks the domain (MX, SPF, DMARC, RDAP registration date, one website fetch), matches it to a Jid file and reads the file''s standing, licences, filings, capital raises, loans and adverse records. Returns signals with sources, legitimacy/capacity/consistency scores (0 to 100, with reasons), a recommendation, a next step, questions to ask, checks and a read (headline, engage | verify_first | do_not_engage, failed checks, lookup links: render the read for humans), and a signed receipt. Businesses only: personal webmail, a disposable address or no confident business match returns assessment individual_or_unverified with no scores. A possible list match is effect review, never a finding. The raw message is hashed and never stored unless retain is true. Not for credit, employment, insurance or housing decisions about individuals.'
security:
- bearer: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
maxLength: 254
domain:
type: string
maxLength: 253
company_name:
type: string
maxLength: 200
context:
type: object
properties:
form_type:
type: string
enum:
- seller_application
- acquisition_inquiry
- buyer_registration
- nda_request
- sourcing_request
- listing_request
- consultation
- partnership
- contact
- other
- vendor_claim
- listing_claim
- sponsor_inquiry
- advertiser
- broker_request
- buyer_inquiry
- seller_inquiry
- data_purchase
message:
type: string
maxLength: 5000
stated_value:
type: number
minimum: 0
description: USD
stated_role:
type: string
enum:
- buyer
- seller
- supplier
- investor
- operator
country:
type: string
pattern: ^[A-Z]{2}$
activity:
type: string
enum:
- general_commerce
- sell_prescription_drugs
- manufacture_drugs
- sell_medical_devices
- haul_freight
- broker_freight
- sell_alcohol
- produce_spirits
- provide_investment_advice
- accept_deposits
- lend
- bill_medicare_medicaid
- healthcare_supplier
- federal_contracting
- charitable_solicitation
- construction
- operate_psilocybin_healing_center
claimed_website:
type: string
description: 'vendor_claim / listing_claim: the website of the business or listing being claimed. Enables the affiliation check.'
stated_location:
type: string
maxLength: 80
description: 'The place or market the sender stated ("Jakarta"): shown on read.sender, never stored'
ip_country:
type: string
pattern: ^[A-Z]{2}$
description: 'Location check: country of the request (e.g. x-vercel-ip-country). Stored.'
ip_region:
type: string
description: 'Location check: ISO 3166-2 region of the request (US-CA or CA). Stored.'
ip_city:
type: string
description: Accepted, not compared, not stored, not returned
ip_asn:
type: integer
description: 'Location check: ASN of the request''s network (hosting/VPN recognition). Not stored.'
browser_timezone:
type: string
description: 'Location check: IANA time zone from the browser. Compared, not stored.'
stated_country:
type: string
pattern: ^[A-Z]{2}$
description: 'Location check: the country the submitter stated (same as context.country; either may be sent)'
ip:
type: string
description: 'Optional raw IP: used in memory for the Tor and network lookups (Jid''s Tor and GeoLite2 copies; IPinfo when enabled). Never stored, hashed or returned.'
phone:
type: string
maxLength: 40
description: 'Optional business phone: validity and country code (compared with the location), in memory only, never stored'
signal:
type: string
description: Jid Signals token from the visitor's browser (the jid_signal form field set by https://jid.com/s/1.js; jid_signal is also accepted). When it verifies, its country, region, city, network type and time zone replace the ip_* fields and browser_timezone. Expired, altered or other-site tokens are skipped, never negative. See /signals.
site:
type: string
description: 'The submitting website''s domain. Binds the signal token loosely: a token issued to another site is skipped.'
summary:
type: boolean
description: Add a short summary written only from the signals.
policy:
type: string
enum:
- strict
- balanced
- permissive
description: How cautious `engage` is. Default balanced.
retain:
type: boolean
description: 'Opt in to keeping the message with the result for 13 months (default: hash only, 30 days).'
anyOf:
- required:
- email
- required:
- domain
responses:
'200':
description: Qualification
content:
application/json:
schema:
$ref: '#/components/schemas/Qualification'
'400':
$ref: '#/components/responses/Error'
'401':
$ref: '#/components/responses/Error'
'402':
$ref: '#/components/responses/Error'
'429':
$ref: '#/components/responses/Error'
components:
schemas:
OutcomeLinks:
type: object
description: 'Keyed calls only: signed one-click URLs that record an outcome (POST /v1/outcomes) without a login.'
properties:
legit:
type: string
sales_pitch:
type: string
spam:
type: string
scam:
type: string
closed:
type: string
good:
type: string
description: 2026-10-05 button, still accepted
junk:
type: string
description: 2026-10-05 button, still accepted
Receipt:
type: object
properties:
receipt_id:
type: string
url:
type: string
statement:
type: object
description: 'Exactly what was signed: type, version, receipt_id, issued_at, issuer, entity, inputs, decision, rules_version, reasons (code, met, effect, fact_ids, source, verified_at, fresh_until), facts (id, predicate, source, value_sha256, verified_at), terms.'
signature:
type: object
properties:
alg:
const: Ed25519
kid:
type: string
canonicalization:
const: sorted-keys-json
sig:
type: string
description: base64url
verify:
type: string
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
required:
- code
- message
Qualification:
type: object
properties:
id:
type: string
assessment:
type: string
enum:
- business
- individual_or_unverified
entity:
type:
- object
- 'null'
properties:
id:
type: string
name:
type: string
confidence:
type: string
enum:
- high
- medium
- low
method:
type: string
relied_on:
type: boolean
url:
type: string
signals:
type: array
items:
type: object
properties:
name:
type: string
label:
type: string
value: {}
effect:
type: string
enum:
- +
- '-'
- neutral
- review
detail:
type: string
source:
type: string
source_url:
type:
- string
- 'null'
verified_at:
type:
- string
- 'null'
legitimacy:
$ref: '#/components/schemas/SubScore'
capacity:
$ref: '#/components/schemas/SubScore'
consistency:
$ref: '#/components/schemas/SubScore'
recommendation:
type: string
enum:
- fast_track
- standard
- verify_first
- low_priority
engage:
type: boolean
description: Binary answer from the shared screen rules (same as /v1/screen) under `policy`. Advisory.
risk:
type: string
enum:
- low
- medium
- high
- unknown
mitigations:
type: array
items:
type: object
properties:
code:
type: string
text:
type: string
engage_policy:
type: string
enum:
- strict
- balanced
- permissive
suggested_next_step:
type: string
questions_to_ask:
type: array
items:
type: string
minItems: 2
maxItems: 4
checks:
type: array
items:
$ref: '#/components/schemas/Check'
read:
$ref: '#/components/schemas/Read'
website_declared:
oneOf:
- $ref: '#/components/schemas/WebsiteDeclared'
- type: 'null'
outcome_links:
$ref: '#/components/schemas/OutcomeLinks'
affiliation:
type:
- object
- 'null'
description: 'Claims only: does the address''s domain match the claimed business (same domain, a registry domain of the business, or a link between the two websites)? A mismatch means manual review, never rejection.'
properties:
status:
type: string
enum:
- matched
- mismatched
- unknown
email_domain:
type:
- string
- 'null'
claimed_domain:
type:
- string
- 'null'
evidence:
type: array
items:
type: object
properties:
text:
type: string
source:
type: string
source_url:
type:
- string
- 'null'
location:
type:
- object
- 'null'
description: 'Present when location inputs were given: the same block as /v1/screen. A mismatch, Tor exit or hosting/VPN network adds risk only alongside another negative signal and never sets engage=false on its own. Jid keeps only ip_country, ip_region, network type and consistent.'
properties:
consistent:
type:
- boolean
- string
description: true, false or "unknown"
reference:
type:
- object
- 'null'
signals:
type: array
items:
type: object
network:
type: object
properties:
type:
type: string
enum:
- tor
- hosting_or_vpn
- other
- unknown
asn:
type:
- integer
- 'null'
source:
type: string
detail:
type: string
summary:
type:
- string
- 'null'
rules_version:
type: string
receipt:
$ref: '#/components/schemas/Receipt'
retention:
type: object
properties:
result_until:
type: string
message_stored:
type: boolean
checks_used:
type: integer
WebsiteDeclared:
type: object
description: 'What a company''s own website states about itself (provenance tier website_declared): identity context only, never a registry result. Present only when no Jid file holds or is associated with the domain.'
properties:
tier:
type: string
enum:
- website_declared
domain:
type: string
legal_name:
type: string
description: As printed, with its legal form
trade_name:
type:
- string
- 'null'
address:
type:
- string
- 'null'
description: As printed; null when the site prints addresses in several states
state:
type:
- string
- 'null'
postal_code:
type:
- string
- 'null'
source_url:
type: string
read_at:
type: string
format: date-time
how:
type: string
note:
type: string
SubScore:
type: object
properties:
score:
type:
- integer
- 'null'
minimum: 0
maximum: 100
description: null when assessment is individual_or_unverified
reasons:
type: array
items:
type: object
properties:
text:
type: string
points:
type: number
Check:
type: object
description: One check from the registry. New checks add rows, never fields.
properties:
id:
type: string
description: 'Stable id: registered, sanctions, threat_feeds, email_address, mail_domain, domain_age, website, affiliation, adverse_records, licence, phone, location, enquiry, funding, complaints, lookalike_domain, email_auth, history'
label:
type: string
group:
type: string
enum:
- identity
- legitimacy
- safety
- location
- capacity
- history
status:
type: string
enum:
- pass
- fail
- unknown
- na
severity:
type: string
enum:
- block
- warn
- info
description: 'What a fail means: block = do not engage, warn = verify first, info = never changes the recommendation'
evidence:
type: string
lookup:
type: object
properties:
label:
type: string
url:
type: string
phrase:
type: string
Read:
type: object
description: 'What to show a human: render this and nothing else.'
properties:
headline:
type: string
examples:
- 'Passed all 7 checks Jid could run. Recommendation: engage.'
- 'Passed 6 of 7 checks Jid could run: sanctions failed. Recommendation: do not engage.'
- 'Passed all 9 checks Jid could run. Not in an official registry Jid covers (Indonesia), so: verify first.'
recommendation:
type: string
enum:
- engage
- verify_first
- do_not_engage
passed:
type: integer
total:
type: integer
description: Checks that ran (status pass or fail) and decide (severity block or warn), plus location consistency, which is counted but never decides
reason:
type: string
description: 'Why a read with no registry match is not engage, e.g. "Not found on the registers Jid checks for Indonesia (LEI records only)". Also in the headline, followed by ", so: verify first".'
not_checked:
type: array
maxItems: 4
items:
type: string
description: Labels of deciding checks that did not run or did not finish
sender:
type: string
description: 'Qualify only, response only (never stored): the Jid Signals location next to the stated place and the company domain''s age'
failed:
type: array
maxItems: 3
items:
type: object
properties:
label:
type: string
evidence:
type: string
lookup:
type: object
lookups:
type: array
maxItems: 4
items:
type: object
properties:
label:
type: string
url:
type: string
file_url:
type: string
subject:
type:
- string
- 'null'
responses:
Error:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearer:
type: http
scheme: bearer
description: 'jid_live_... key from https://jid.com/pricing (free key: no card).'
externalDocs:
description: API reference
url: https://jid.com/api-docs