# 2s > Unified JSON REST API for AI agents. Pay per call in USDC on Base via x402. No accounts, no API keys, no monthly fees — just a USDC-funded EVM wallet on Base. ## How it works 1. Call any endpoint with no auth → receive `402 Payment Required` with the x402 PaymentRequirements envelope. 2. Sign an `EIP-3009 transferWithAuthorization` from your Base wallet for the quoted USDC amount. 3. Retry the call with the base64-encoded payload in the `PAYMENT-SIGNATURE` header (or `X-PAYMENT` for v1 clients) → receive `200 OK` plus an `X-PAYMENT-TX` header pointing at the on-chain settlement. Gas is paid by the facilitator. The caller only needs USDC, not ETH. ## Machine-readable resources - [https://2s.io/api/directory](https://2s.io/api/directory) — endpoint catalog (JSON) - [https://2s.io/api/openapi](https://2s.io/api/openapi) — OpenAPI 3.1 spec - [https://2s.io/.well-known/x402](https://2s.io/.well-known/x402) — x402 service manifest - [https://2s.io/.well-known/mcp/server-card.json](https://2s.io/.well-known/mcp/server-card.json) — MCP server card (SEP-1649) - [https://x402.org](https://x402.org) — protocol spec ## SDKs - TypeScript: `npm i @2sio/sdk` — - Python: `pip install 2sio` — - MCP server: `npx -y @2sio/mcp` — - Source + examples: ## Settlement - Network: `base` - Asset: USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`) - Treasury: `0x2b6D4988Db4723E6908Db86Ab2b8dFBc51FC32C5` - Facilitator: `https://api.cdp.coinbase.com/platform/v2/x402` ## Endpoints (39) - `POST /api/ai/describe-image` — Describe an image. POST { imageUrl, instruction? }. Returns { imageUrl, altText (5-15 word accessibility text), description (2-3 sentences), contentType (photograph|illustration|screenshot|diagram|document|mixed|other), text (verbatim OCR transcription, "" if none), mainObjects[], dominantColors[] (hex) }. Accepts JPEG, PNG, GIF, WebP. 1MB image size cap. ($0.018 USDC per call) - `POST /api/ai/extract` — Extract structured data from a webpage. POST { url, schema, instruction? }. The schema is a JSON Schema object (top-level type:"object") describing the shape you want back; output is guaranteed to conform. Returns { url, finalUrl, extracted, meta:{ truncated } }. ($0.03 USDC per call) - `POST /api/ai/screenshot` — Render a URL as a screenshot. POST { url, width?, height?, fullPage?, format?, quality?, waitUntil?, timeoutMs?, deviceScaleFactor?, blockAds? }. Returns raw image bytes (no JSON envelope) with X-2s-Render-Ms and X-2s-Image-Bytes headers. Viewport clamped 320-3840 × 320-2160. Timeout clamped 1-15s. Defaults: 1280×720 PNG, networkidle2 wait, ad-blocking on. Use cases: visual verification, archival, change detection, OG-card generation, RSS thumbnails. ($0.0075 USDC per call) - `POST /api/ai/summarize` — Summarize a webpage. POST { url, instruction? }. Returns { url, finalUrl, summary (1-3 sentences), keyPoints (3-7 bullets), title, audience, estimatedReadingMinutes, meta:{ truncated } }. Sibling to /api/ai/extract — use extract when you need a typed payload conforming to your own schema; use summarize when you want a ready-made digest. ($0.0225 USDC per call) - `POST /api/ai/translate` — Translate text. POST { text, targetLanguage, sourceLanguage? } — language codes are BCP-47 (e.g. "en", "es-MX", "zh-Hans"). Source auto-detected when omitted. Returns { text, targetLanguage, detectedSourceLanguage, confidence (high|medium|low) }. Best for short-to-medium passages; chunk long documents on your side. ($0.0075 USDC per call) - `GET /api/airport/lookup` — Look up an airport by 3-letter IATA (e.g. SFO) or 4-letter ICAO (e.g. KSFO) code. Query: code (3-5 chars, alphanumeric). Returns { airport: { id, ident, type, name, latitude, longitude, elevationFt, continent, isoCountry, isoRegion, municipality, scheduledService, icaoCode, iataCode, gpsCode, localCode, wikipediaLink } } or 404 NOT_FOUND. ($0.001 USDC per call) - `GET /api/airport/near` — Airports within a radius of a coordinate, sorted by distance. Query: lat (-90..90), lon (-180..180), radius_km (1-2000, default 200), limit (1-100, default 20), type (optional: large_airport|medium_airport|small_airport|heliport|seaplane_base|balloonport|closed), country (optional 2-letter ISO 3166-1), scheduled_service (optional bool, true = commercial-service airports only). Returns { query, count, airports: [{ id, ident, name, iataCode, icaoCode, type, latitude, longitude, distanceKm, ... }] }. ($0.001 USDC per call) - `POST /api/barcode/generate` — Generate QR / Aztec / Data Matrix / PDF417 codes from structured payloads (url, wifi, vcard, vevent, email, sms, tel, geo, bitcoin, json, text). QR supports rounded or dotted modules, solid colors or linear/radial gradients, transparent backgrounds, configurable error correction, and a centered logo image (URL or data URI). ($0.001 USDC per call) - `GET /api/census/zipcode` — US Census ACS 5-year demographics for a ZIP code (ZCTA). Returns population, median age, median household income, poverty rate, household composition, race + ethnicity breakdown, education attainment, workforce (with computed unemployment rate), and housing (with computed owner-occupancy rate and median rent/home value). Backed by ~33k ZCTAs pre-ingested from api.census.gov; refreshed annually. Public-domain US government data. ($0.001 USDC per call) - `GET /api/climate/station-near` — Find NOAA GHCN-Daily weather stations near a coordinate. Returns up to 100 stations within a configurable radius (default 500 km), sorted by distance. Each station includes id, name, lat/lon, elevation, country/state, and GSN/HCN/WMO flags. Backed by a ~132k-station registry refreshed monthly from ncei.noaa.gov. ($0.001 USDC per call) - `GET /api/countdown/gif` — Animated countdown GIF from the current UTC time to endDate. Always uncached. Supports 5 templates (default, minimal, neon, retro, corporate) and full customization: colors, fonts, dimensions, padding, cell padding, labels, dividers. Animates for `seconds` frames at `fps`. ($0.006 USDC per call) - `GET /api/crypto/address-validate` — Validate a cryptocurrency address with full checksum verification (not just regex). Returns {chain, address, valid, canonical, format, reason}. Chains: btc (P2PKH, P2SH, Bech32 SegWit v0, Taproot Bech32m), eth (full EIP-55 checksum; non-checksummed flagged), sol (Ed25519 32-byte Base58), ltc (Base58Check L.../M.../3... + ltc1 Bech32), trx (T-prefix Base58Check 0x41), xrp (r-prefix custom Base58), bch (legacy Base58Check + bitcoincash:q... CashAddr). Catches typos via cryptographic checksum; canonical field returns the checksummed/lowercased form. ($0.001 USDC per call) - `GET /api/crypto/gas-oracle` — Live EVM gas oracle. Returns latest block baseFeePerGas + slow/standard/fast tiers derived from priority-fee percentiles (p25/p50/p75) over the trailing 4 blocks, plus a 21,000-gas transfer cost estimate in the chain native unit. Chains: base, ethereum, polygon, arbitrum, optimism. Real-time post-training data, ~5s freshness. ($0.001 USDC per call) - `GET /api/dns/lookup` — Resolve a hostname over public DNS and return parsed records. Query: host (required FQDN), types (comma-separated: A,AAAA,MX,TXT,NS,CAA,SRV,CNAME,PTR,SOA — default A,AAAA,MX,TXT,NS), resolver (cloudflare|google|quad9|opendns, optional). Returns one normalized JSON shape per record type with per-type error pass-through. Reserved/local TLDs (.local, .internal, .invalid, .test, localhost) are rejected. 4s per-query timeout. ($0.001 USDC per call) - `GET /api/domain/whois` — Modern WHOIS via RDAP. Query: domain (e.g. example.com). Returns { domain, ldhName, handle, registrar:{ name, ianaId, url, abuseEmail, abusePhone }, registeredAt, expiresAt, updatedAt, statuses (camelCase ICANN EPP codes), nameservers[], dnssecSigned, rdapUrl }. GDPR: registrant personal data is generally redacted upstream and not returned. Some TLDs without RDAP are not supported and return 404 TLD_NOT_SUPPORTED. ($0.001 USDC per call) - `GET /api/earth/now` — Situational awareness for a coordinate: recent earthquakes (USGS) and active wildfires (NIFC) within a configurable radius. Returns each with distance-from-query in km, sorted nearest-first. Multi-source synthesis from free US Government feeds. Real-time, post-training data. ($0.0012 USDC per call) - `GET /api/geo/ip` — Geolocate an IPv4/IPv6 address to country, region, city, and coordinates. ($0.001 USDC per call) - `GET /api/geocode/address` — Forward geocoding — free-text address or place name → latitude/longitude plus structured address components (houseNumber, road, suburb, city, county, state, postcode, country, countryCode). Query: q (2-500 chars), limit (1-10, default 5), country (optional 2-letter ISO 3166-1 bias). Underlying data is OpenStreetMap (ODbL). Sister: /api/geocode/reverse. ($0.001 USDC per call) - `GET /api/geocode/reverse` — Reverse geocoding — latitude/longitude → nearest formatted address plus structured components (houseNumber, road, suburb, city, county, state, postcode, country, countryCode). Query: lat (-90..90), lon (-180..180). Underlying data is OpenStreetMap (ODbL). Sister: /api/geocode/address. ($0.001 USDC per call) - `POST /api/hash/compute` — Compute one or more cryptographic digests (MD5, SHA-1, SHA-2 family, SHA-3 family, BLAKE2) of a string or hex/base64-encoded byte buffer. Returns hex or base64-encoded digests. ($0.001 USDC per call) - `POST /api/image/compress` — Compress an image. POST exactly one of { url } or { imageBase64 }, plus optional { format?: auto|png|jpeg|webp|avif (default auto = keep input format), quality?: 1-100 (default 75), lossy?: bool (default true), effort?: 1-10 (default 6) }. Returns compressed image bytes directly with X-2s-* headers: Original-Bytes, Compressed-Bytes, Saved-Percent, Output-Format, Source-Format, Source-Width, Source-Height, Process-Ms. Limits: 5MB URL fetch, ~3MB inline body, 4096 × 4096 input pixels. Animated GIF input becomes animated WebP when format=webp or auto. ($0.0024 USDC per call) - `POST /api/ipinfo/bulk` — Geolocate up to 100 IPv4/IPv6 addresses in a single call. Returns per-IP results in input order; failed entries include an error object instead of geo fields. ($0.006 USDC per call) - `GET /api/law/case-search` — Search US court opinions (SCOTUS, federal circuits, state appellate/supreme — ~9M opinions). Query by free-text (party names, keywords, docket #, citation). Filter by court slug (e.g., "scotus", "ca9", "nysupct"), filing date range, and order (relevance/dateFiled-desc/dateFiled-asc/citeCount-desc). Returns clusterId, caseName, court, year, docket, reporter citations, citationCount, snippet, canonical URL. Discovery-side complement to case-verify. Backed by CourtListener (Free Law Project); underlying opinions are public domain. ($0.0036 USDC per call) - `POST /api/law/case-verify` — Verify US legal case citations in a passage of text. POST { text } where text contains one or more citations (e.g. "Marbury v. Madison, 5 U.S. 137 (1803)"). Returns per-citation results with canonical case name, court, year, docket, citationCount, and a public CourtListener URL — or flags the citation as unverified. Anti-hallucination check for legal LLM output. Underlying opinions are public domain; CourtListener (Free Law Project) is the corpus. ($0.006 USDC per call) - `GET /api/law/federal-register` — Search the US Federal Register — proposed rules, final rules, notices, and presidential documents. Filter by free-text term, document type (RULE/PRORULE/NOTICE/PRESDOCU), agency slug (e.g., epa, fda, sec), and publication date range. Returns document_number, type, title, abstract, FR citation, agencies, publication_date, effective_on, comments_close_on, htmlUrl, pdfUrl, rawTextUrl. Public-domain US government data. Real-time — published daily, past LLM training cutoff. ($0.001 USDC per call) - `POST /api/law/opinion` — Fetch the full text of a US court opinion by CourtListener opinion ID OR by citation. Returns plain text (preferred), HTML fallback, case metadata (case name, court, year, docket, citation), opinion type (lead/concurrence/dissent), author, and a list of alternate opinions in the same cluster. POST { opinionId?: number, citation?: string } — exactly one required. Anti-hallucination follow-up to case-verify: once you confirm the citation exists, fetch the text. Backed by CourtListener (public-domain underlying corpus). ($0.0048 USDC per call) - `POST /api/law/sanctions-check` — Fuzzy-match a name (person, company, vessel, aircraft) against the US Treasury OFAC Specially Designated Nationals list. POST { query, threshold?, limit?, sourceList? }. Returns ranked matches with similarity scores, entity type, sanctions programs, aliases, and remarks. Threshold default 0.4; scores ≥ 0.85 flagged as hasHighConfidenceMatch. List refreshed daily from public US Treasury data. ($0.0048 USDC per call) - `GET /api/papers/search` — Unified scientific literature search across arXiv (preprints), PubMed (biomedical), and Semantic Scholar (cross-field, with citation counts). Returns a flat array of papers with stable schema: source, sourceId, doi, title, authors, abstract, year, publishedAt, citationCount, url, pdfUrl. Partial failures surface in the errors array rather than failing the whole call. Optional filters: since (YYYY-MM-DD), sources (subset), limit (max 20 per source). ($0.0024 USDC per call) - `GET /api/patents/detail` — Full US patent application file-wrapper detail by application number. Returns bibliographic data (title, inventors, applicants, dates, status, examiner, art unit, docket #, confirmation #) plus the file-wrapper event timeline (filing, IDS, Office Actions, allowance, abandonment, …), continuity chain (parent / continuation / divisional / national stage), recorded assignments (assignor → assignee with reel/frame + conveyance text), and foreign priority claims under 35 USC § 119. Application number is the 6-10 digit USPTO ID (e.g. 18566276). ($0.0018 USDC per call) - `GET /api/patents/documents` — List every document in the file wrapper for a US patent application. Returns each document with its USPTO code (e.g. CTNF non-final OA, CTFR final OA, IDS, WCLM claims worksheet, NOA notice of allowance), human-readable description, official date, direction (INTERNAL/INCOMING/OUTGOING), and available formats with page counts. Includes patentCenterUrl pointing at the public USPTO Patent Center documents page for direct PDF download. Application number is the 6-10 digit USPTO ID. ($0.0018 USDC per call) - `GET /api/patents/search` — Search US patent applications and grants via the USPTO Open Data Portal. Query: q (required, 2+ chars), yearFrom / yearTo (optional filing-year bounds), applicationType (optional: Utility|Design|Plant|Reissue), limit (1-100, default 10), offset (0-based, default 0). Returns { total, returned, offset, limit, hits[{ applicationNumber, title, applicationType, firstInventor, inventors[], applicants[], filingDate, effectiveFilingDate, status:{ code, description, updatedAt }, cpcSymbols[], uspcSymbol, url }] }. URLs link to USPTO Patent Center for the public file wrapper. ($0.0018 USDC per call) - `GET /api/poi/near` — Find points of interest near a coordinate. Backed by OpenStreetMap via the Overpass API (free, public, ODbL). Returns name, OSM id (e.g. node/123 — deep-linkable to openstreetmap.org), latitude, longitude, distance in meters, composed street address (when present), phone, website, opening hours, brand, and cuisine tags. Results sorted nearest-first. Supported categories: restaurant, cafe, bar, fast_food, gas_station, ev_charging, parking, atm, bank, hospital, pharmacy, clinic, doctor, dentist, police, fire_station, post_office, library, toilets, school, university, supermarket, convenience, hotel, hostel, museum, attraction, park, playground. Query: lat (-90..90), lon (-180..180), category (one of the supported names), radius_m (1-10000, default 1000), limit (1-100, default 20). ($0.001 USDC per call) - `GET /api/quakes/recent` — Recent earthquakes near a coordinate. Returns each quake with magnitude, place name, time (ISO), latitude/longitude/depth, tsunami flag, USGS event URL, and distance-from-query in km — sorted by time descending. Real-time data, post-LLM-training-cutoff. Backed by USGS FDSN event API (public domain). Query: lat (-90..90), lon (-180..180), radius_km (1-1000, default 500), hours (1-720, default 24), min_magnitude (0-10, default 2.0). ($0.001 USDC per call) - `GET /api/sunrise/compute` — Compute sunrise, sunset, solar noon, and civil/nautical/astronomical twilight times for a coordinate + date. Query: lat (-90..90), lon (-180..180), date (YYYY-MM-DD). All times returned as ISO 8601 UTC. At high latitudes near solstices an event may not occur (polar day/night) — those fields return null and a note is included. dayLengthMinutes is the sunrise→sunset interval. ($0.001 USDC per call) - `GET /api/tides/now` — Next high/low tide predictions near a coordinate. Query: lat (-90..90), lon (-180..180), radius_km (1-500, default 100), hours (1-72, default 24). Returns { query, station:{ id, name, latitude, longitude, state, distanceKm }, predictions[{ time (station local), type: "high"|"low", heightMeters }], source }. Returns 404 NO_STATION if no NOAA tide station is within radius. Heights are referenced to MLLW (Mean Lower-Low Water). ($0.001 USDC per call) - `GET /api/url/clean` — Fetch any URL and return the article content as clean markdown (with optional plain-text version). Strips nav, footer, ads, sidebars, scripts, styles, comments. Heuristic article extraction picks
/
/ role=main / densest content block. SSRF-guarded, 512KB body cap, 8s timeout, 5 redirects max. Returns { url, finalUrl, title, markdown, text, wordCount, sourceBytes }. Sister to /api/url/unfurl (which returns metadata + 500-char preview); use clean when you want the FULL article for LLM consumption. ($0.00108 USDC per call) - `GET /api/url/unfurl` — Fetch any URL and extract structured page metadata: title, description, og:image, canonical, favicon, site name, author, published time, language, and the first ~500 chars of body text. SSRF-guarded against private networks. 8s timeout, 512 KB max body. Returns the parsed metadata plus the raw og:/twitter:/itemprop meta dictionary for inspection. ($0.001 USDC per call) - `GET /api/weather/zip` — Current weather conditions for a US ZIP code (temperature, wind, humidity, conditions). Backed by the US National Weather Service (api.weather.gov) — public domain, no rate-limit pressure on commercial use. ($0.0012 USDC per call) - `GET /api/wikipedia/summary` — Fetch a Wikipedia article summary in any of 30 supported languages. Returns title, displayTitle, lang, pageId, description, extract (plain text), extractHtml, lead image, canonical URLs, last-modified timestamp, word count, license, and an attribution string. Backed by https://.wikipedia.org/api/rest_v1/page/summary. Content is CC BY-SA 4.0 with attribution provided. ($0.001 USDC per call) ## Sample paying client ```js import { createPaymentHeader } from 'x402/client' import { privateKeyToAccount } from 'viem/accounts' const account = privateKeyToAccount(process.env.PRIVATE_KEY) const probe = await fetch('https://2s.io/api/weather/zip?zip=94103') const { accepts } = await probe.json() // canonical x402 envelope: { x402Version, accepts, error } const header = await createPaymentHeader(account, 1, accepts[0]) const paid = await fetch('https://2s.io/api/weather/zip?zip=94103', { headers: { 'PAYMENT-SIGNATURE': header }, }) const data = await paid.json() ```