openapi: 3.2.0 info: title: 2s — the (most) everything Trade API version: '1' summary: The (most) everything API. description: 'The (most) everything API for AI agents: 575+ pay-per-call endpoints on one origin.' contact: name: 2s url: https://2s.io email: alley@2s.io x-logo: url: https://2s.io/icon-512.png altText: 2s x-guidance: 'Pay-per-call REST API for AI agents — hundreds of endpoints returning ground-truth data (US public records, company & legal identifiers, finance/SEC, crypto/web3, security & CVEs, medical codes, weather & geocoding, agriculture, energy, maritime, music, and more). Every endpoint is paid per call in USDC via x402 (Base or Solana) — no API key, no signup. Call any endpoint with no auth to get a 402 PaymentRequirements envelope, sign it (EIP-3009 on Base, partial SPL transfer on Solana), and retry with the PAYMENT-SIGNATURE header. Add ?trial=1 for one free real call per endpoint per hour to test before paying. To discover the right endpoint: GET https://2s.io/api/directory for the full catalog, or GET https://2s.io/api/search/endpoints?q= for a ranked match. Per-call price is on each operation as x-payment-info (from $0.001). Batch up to 50 calls behind one payment via POST https://2s.io/api/batch/run.' servers: - url: https://2s.io tags: - name: Trade paths: /api/trade/commodity-resolve: get: tags: - Trade summary: Cross-walk a traded-good code across HS (6-digit description: Cross-walk a traded-good code across HS (6-digit international Harmonized System) HTS (US 10-digit import) Schedule B (US 10-digit export) NAICS industry. Pass the system + code and get the shared HS6, the official description, the matching Schedule B and HTS national lines, the NAICS industry(ies), and the SITC code. The join an import/export, customs, or supply-chain agent needs to move between the export schedule, the import tariff schedule, the international HS level, and the industry that makes the good -- all keyed on the globally-harmonized HS6 bridge. Backed by bundled public-domain US Census Foreign Trade concordances (Schedule B + HTS, latest annual). For a 10-digit input the NAICS is narrowed to that exact national line; cross-schedule lines are surfaced via the shared HS6 and flagged in notes. Companion to trade.tariff (duty rates) and business.naics (industry detail). operationId: trade_commodity-resolve deprecated: false security: - x402Payment: [] responses: '200': description: 'Normalized envelope: items = [one commodity crosswalked across HS/HTS/Schedule B/NAICS via the HS6 bridge]; total = 1.' content: application/json: schema: type: object required: - data - meta properties: data: type: object properties: ok: type: boolean enum: - true items: type: array items: type: object properties: resolvedFrom: type: string enum: - hs - hts - scheduleb input: type: string hs6: type: string nullable: true description: type: string nullable: true naics: type: array items: type: string sitc: type: array items: type: string scheduleB: type: array items: type: string description: US export (Schedule B) 10-digit lines under this HS6. hts: type: array items: type: string description: US import (HTS) 10-digit lines under this HS6. notes: type: array items: type: string required: - resolvedFrom - input - hs6 - description - naics - sitc - scheduleB - hts - notes additionalProperties: false total: type: integer nullable: true description: Total matching rows upstream; null when unknown. source: $ref: '#/components/schemas/Source' required: - ok - items - total - source additionalProperties: false meta: $ref: '#/components/schemas/CallMeta' '400': $ref: '#/components/responses/BadRequest' '402': $ref: '#/components/responses/PaymentRequired' '405': $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/UpstreamError' x-2s-id: trade.commodity-resolve x-2s-version: null x-2s-price: usd: 0.009 x-2s-accepts: - x402 x-2s-response-shape: normalized x-payment-info: price: mode: fixed currency: USD amount: '0.009000' protocols: - x402: {} parameters: - name: system in: query required: true description: 'Which system the input code is in: hs (6-digit intl), hts (US import), scheduleb (US export).' schema: type: string enum: - hs - hts - scheduleb - name: code in: query required: true description: The commodity code, dots optional, e.g. 090121, 0901210000, or 8703.23.00. schema: type: string minLength: 4 maxLength: 14 - $ref: '#/components/parameters/TrialMode' /api/trade/flows: get: tags: - Trade summary: Annual international merchandise-trade flows from UN description: 'Annual international merchandise-trade flows from UN Comtrade (HS classification). Pass reporter (the country whose trade you want; ISO-2/ISO-3 like ''US''/''USA'', a UN M49 number, or ''World''), optional partner (counterparty; default World), year (YYYY), flow (export|import), and commodity: ''TOTAL'' (all goods, default), a specific HS code (''27'', ''8703''), or ''AG2''/''AG4''/''AG6'' for a top-commodity breakdown at the 2/4/6-digit level. Returns trade value (USD), net weight, quantity, and the HS commodity, sorted by value. Country names are resolved from Comtrade''s own reference data.' operationId: trade_flows deprecated: false security: - x402Payment: [] responses: '200': description: 'Normalized envelope: items = trade-flow records (sorted by value desc); total = upstream row count; meta.query echoes the resolved request (incl. M49 codes).' content: application/json: schema: type: object required: - data - meta properties: data: type: object properties: ok: type: boolean enum: - true items: type: array items: type: object properties: reporter: type: string nullable: true reporterIso: type: string nullable: true partner: type: string nullable: true partnerIso: type: string nullable: true flow: type: string nullable: true period: type: string nullable: true commodityCode: type: string nullable: true commodity: type: string nullable: true valueUsd: type: number nullable: true netWeightKg: type: number nullable: true quantity: type: number nullable: true quantityUnit: type: string nullable: true required: - reporter - reporterIso - partner - partnerIso - flow - period - commodityCode - commodity - valueUsd - netWeightKg - quantity - quantityUnit additionalProperties: false total: type: integer nullable: true description: Total matching rows upstream; null when unknown. source: $ref: '#/components/schemas/Source' meta: type: object properties: query: type: object properties: reporter: type: string reporterCode: type: integer partner: type: string partnerCode: type: integer year: type: string flow: type: string commodity: type: string required: - reporter - reporterCode - partner - partnerCode - year - flow - commodity additionalProperties: false required: - query additionalProperties: false required: - ok - items - total - source additionalProperties: false meta: $ref: '#/components/schemas/CallMeta' '400': $ref: '#/components/responses/BadRequest' '402': $ref: '#/components/responses/PaymentRequired' '405': $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/UpstreamError' x-2s-id: trade.flows x-2s-version: null x-2s-price: usd: 0.009 x-2s-accepts: - x402 x-2s-response-shape: normalized x-payment-info: price: mode: fixed currency: USD amount: '0.009000' protocols: - x402: {} parameters: - name: reporter in: query required: true description: 'Reporting country: ISO-2/ISO-3 ("US"/"USA"), UN M49 number, or "World".' schema: type: string minLength: 2 maxLength: 40 - name: partner in: query required: false description: Partner/counterparty country (same formats). Default "World" (all partners aggregated). schema: type: string minLength: 2 maxLength: 40 default: World - name: year in: query required: true description: Calendar year (YYYY). Comtrade annual data typically lags ~6-12 months. schema: type: string pattern: ^\d{4}$ - name: flow in: query required: false description: Trade direction from the reporter's perspective. Default export. schema: type: string enum: - export - import default: export - name: commodity in: query required: false description: '"TOTAL" (all goods, default), a specific HS code ("27", "8703"), or "AG2"/"AG4"/"AG6" for a top-commodity breakdown.' schema: type: string minLength: 2 maxLength: 8 default: TOTAL - name: limit in: query required: false description: Max rows to return (1-100), sorted by trade value desc. Default 25. schema: type: integer minimum: 1 maximum: 100 default: 25 - $ref: '#/components/parameters/TrialMode' /api/trade/locode: get: tags: - Trade summary: Look up or search UN/LOCODE - the United Nations Code for description: 'Look up or search UN/LOCODE — the United Nations Code for Trade and Transport Locations (~116k locations, all countries). Pass `locode` for an exact code (e.g. USNYC or ''US NYC''). Or pass `query` to search location names, optionally filtered by `country` (ISO 3166 alpha-2) and `function` (port, rail, road, airport, postal, multimodal, fixed, border). Each result: locode, name, country, subdivision, transport functions, entry status, IATA code where it differs, and coordinates. UN/LOCODE is the standard location identifier in shipping schedules, EDI messages, and customs documents.' operationId: trade_locode deprecated: false security: - x402Payment: [] responses: '200': description: 'Normalized envelope: items = UN/LOCODE entries (single exact match, or ranked name-search results); total = match count.' content: application/json: schema: type: object required: - data - meta properties: data: type: object properties: ok: type: boolean enum: - true items: type: array items: type: object properties: locode: type: string description: 5-character UN/LOCODE (country + location). country: type: string description: ISO 3166 alpha-2 country code. location: type: string description: 3-character location part of the code. name: type: string description: Place name (with diacritics). nameAscii: type: string description: Place name without diacritics. subdivision: type: object properties: code: type: string name: type: string nullable: true required: - code - name additionalProperties: false nullable: true description: ISO 3166-2 subdivision (state/province), when assigned. functions: type: object properties: raw: type: string description: Raw 8-position UN/LOCODE function classifier. list: type: array items: type: string description: Decoded transport functions (port, rail terminal, airport, …). required: - raw - list additionalProperties: false status: type: object properties: code: type: string meaning: type: string nullable: true required: - code - meaning additionalProperties: false nullable: true description: Entry status code + meaning (e.g. AA = approved by national agency). iata: type: string nullable: true description: IATA code, only when it differs from the location part. coordinates: type: object properties: lat: type: number lon: type: number required: - lat - lon additionalProperties: false nullable: true updated: type: string nullable: true description: Last-change marker from the source list (YYMM). required: - locode - country - location - name - nameAscii - subdivision - functions - status - iata - coordinates - updated additionalProperties: false total: type: integer nullable: true description: Total matching rows upstream; null when unknown. source: $ref: '#/components/schemas/Source' page: type: object properties: number: type: integer size: type: integer pages: type: integer nullable: true required: - number - size - pages additionalProperties: false required: - ok - items - total - source additionalProperties: false meta: $ref: '#/components/schemas/CallMeta' '400': $ref: '#/components/responses/BadRequest' '402': $ref: '#/components/responses/PaymentRequired' '405': $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/UpstreamError' x-2s-id: trade.locode x-2s-version: null x-2s-price: usd: 0.0025 x-2s-accepts: - x402 x-2s-response-shape: normalized x-payment-info: price: mode: fixed currency: USD amount: '0.002500' protocols: - x402: {} parameters: - name: locode in: query required: false description: Exact UN/LOCODE to look up (e.g. USNYC or 'US NYC'). Pass this OR query. schema: type: string pattern: ^[A-Za-z]{2}[\s-]?[A-Za-z0-9]{3}$ - name: query in: query required: false description: Location name to search (e.g. Rotterdam). Pass this OR locode. schema: type: string minLength: 2 maxLength: 120 - name: country in: query required: false description: Restrict query-mode results to one country (ISO 3166 alpha-2, e.g. NL). schema: type: string pattern: ^[A-Za-z]{2}$ - name: function in: query required: false description: Restrict query-mode results to locations with this transport function. schema: type: string enum: - port - rail - road - airport - postal - multimodal - fixed - border - name: limit in: query required: false description: Max query-mode results, 1–50 (default 10). schema: type: integer minimum: 1 maximum: 50 - $ref: '#/components/parameters/TrialMode' /api/trade/tariff: get: tags: - Trade summary: Look up or search the US Harmonized Tariff Schedule (HTS / description: 'Look up or search the US Harmonized Tariff Schedule (HTS / HS codes). Pass `code` for an exact HTS number (dots optional) — returns that line plus its 10-digit statistical suffixes with duty rates. Or pass `query` for free-text search (e.g. ''electric toothbrush'', ''roasted coffee'') → ranked candidate HS codes by hierarchical heading. Each result: htsno, chapter, description, full heading path, units, and duty rates (general/MFN, special/FTA, column-2). ~29.6k lines, public-domain USITC data. The deterministic backbone for tariff classification in import/export and ERP item setup.' operationId: trade_tariff deprecated: false security: - x402Payment: [] responses: '200': description: 'Normalized envelope: items = HTS lines (exact match + suffixes, or ranked search candidates); total = match count.' content: application/json: schema: type: object required: - data - meta properties: data: type: object properties: ok: type: boolean enum: - true items: type: array items: type: object properties: htsno: type: string chapter: type: string nullable: true description: type: string nullable: true heading: type: string nullable: true description: Full hierarchical heading path (ancestors > leaf). units: type: array items: type: string nullable: true duty: type: object properties: general: type: string nullable: true description: General (MFN) duty rate. special: type: string nullable: true description: Special (FTA / preference) rate. other: type: string nullable: true description: Column 2 rate. required: - general - special - other additionalProperties: false required: - htsno - chapter - description - heading - units - duty additionalProperties: false total: type: integer nullable: true description: Total matching rows upstream; null when unknown. source: $ref: '#/components/schemas/Source' page: type: object properties: number: type: integer size: type: integer pages: type: integer nullable: true required: - number - size - pages additionalProperties: false required: - ok - items - total - source additionalProperties: false meta: $ref: '#/components/schemas/CallMeta' '400': $ref: '#/components/responses/BadRequest' '402': $ref: '#/components/responses/PaymentRequired' '405': $ref: '#/components/responses/MethodNotAllowed' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/UpstreamError' x-2s-id: trade.tariff x-2s-version: null x-2s-price: usd: 0.0045 x-2s-accepts: - x402 x-2s-response-shape: normalized x-payment-info: price: mode: fixed currency: USD amount: '0.004500' protocols: - x402: {} parameters: - name: code in: query required: false description: Code to look up. schema: type: string pattern: ^[0-9.\s]{4,14}$ - name: query in: query required: false description: Free-text search query. schema: type: string minLength: 2 maxLength: 120 - name: limit in: query required: false description: Maximum number of results to return. schema: type: integer minimum: 1 maximum: 50 - $ref: '#/components/parameters/TrialMode' components: schemas: Source: type: object description: 'Provenance of the data: upstream provider, source URL, and license.' properties: provider: type: string description: Upstream data provider. url: type: string description: Source URL or documentation link. license: type: string description: License / usage terms for the data. CallMeta: type: object description: Per-call meta envelope — endpoint id, cost, caller kind, settlement details. X402PaymentRequiredV2: type: object description: x402 v2 PaymentRequired envelope. Pick any entry from accepts[], sign for that rail, retry with the PAYMENT-SIGNATURE header. required: - x402Version - accepts properties: x402Version: type: integer const: 2 error: type: string description: Human-readable reason payment is required. resource: type: string description: The resource URL being purchased. accepts: type: array description: Payment requirement options, one per supported network (Base USDC, Solana USDC). items: type: object required: - scheme - network - amount - asset - payTo - maxTimeoutSeconds properties: scheme: type: string enum: - exact network: type: string description: CAIP-2 network id, e.g. "eip155:8453" (Base) or "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp". amount: type: string description: Price in atomic asset units (USDC has 6 decimals). asset: type: string description: Asset contract address / mint. payTo: type: string description: Treasury address to pay. maxTimeoutSeconds: type: integer extra: type: object description: 'Rail-specific extras (EVM: EIP-712 domain name/version; Solana: feePayer).' additionalProperties: true extensions: type: object description: Optional discovery metadata (e.g. bazaar input/output schemas). additionalProperties: true responses: PaymentRequired: description: Payment required. Body contains the x402 PaymentRequirements envelope with a multi-network accepts array; the per-call price is in accepts[].amount (and on the operation as x-2s-price). Sign for whichever rail you hold USDC on (EIP-3009 for Base, partial SPL transfer for Solana) and retry with the PAYMENT-SIGNATURE header (X-PAYMENT also accepted for v1 clients). content: application/json: schema: $ref: '#/components/schemas/X402PaymentRequiredV2' UpstreamError: description: Upstream provider error. MethodNotAllowed: description: Method not allowed — see `Allow` header for the supported method. ServerError: description: Internal server error. BadRequest: description: Bad request — invalid parameters. parameters: TrialMode: name: trial in: query required: false description: 'Try before you buy. Set to 1 for one free real call per endpoint per hour — no wallet or payment needed — to verify the endpoint before paying. Equivalent to sending the "X-2s-Trial: 1" request header. Works on every endpoint.' schema: type: integer enum: - 1 securitySchemes: x402Payment: type: apiKey in: header name: PAYMENT-SIGNATURE description: 'x402 protocol v2: base64-encoded PaymentPayload. Call any paid endpoint without auth to receive a 402 with a multi-network PaymentRequirements envelope. Sign for either rail: EIP-3009 transferWithAuthorization (Base USDC) OR a partial SPL token transfer (Solana USDC). Retry with PAYMENT-SIGNATURE header. X-PAYMENT is also accepted for v1 buyer clients. See https://x402.org.'