{"_id":"@a3api/node","_rev":"3-c629e3edb06e0278fe9a44822f84800b","name":"@a3api/node","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@a3api/node","version":"0.1.0","keywords":["a3","age-assurance","age-verification","ab-1043","coppa"],"license":"MIT","_id":"@a3api/node@0.1.0","maintainers":[{"name":"digital_arcadia","email":"connect@digital-arcadia.com"}],"dist":{"shasum":"fea7ac6248f2c20e87da66e2560c413754c1dda8","tarball":"https://registry.npmjs.org/@a3api/node/-/node-0.1.0.tgz","fileCount":7,"integrity":"sha512-c96OELAZXDKSsU3Aw5FYN5varIsFQQySZMMYGAcEgl9Vp9NW/UpeVbqwP2EczspSb8rENBvabHw2cz3AhOxHTA==","signatures":[{"sig":"MEYCIQDnlyqq/N7JwxW97yLa+SoMCYA7xfYrvbdpStmb7n4qpgIhAKJpOicmSMybmu9pMvV4Vul+5SX8vMDLXlhc2nIZCACq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42941},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"acb03cdc18073dcfab784ed5783c5cd78e8feb5e","private":false,"scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest"},"_npmUser":{"name":"digital_arcadia","email":"connect@digital-arcadia.com"},"_npmVersion":"10.8.2","description":"Official Node.js client for the A3 Age Assurance API","directories":{},"sideEffects":false,"_nodeVersion":"20.10.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^2.0.0","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/node_0.1.0_1772314124682_0.5559363771604255","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@a3api/node","version":"0.1.1","keywords":["a3","age-assurance","age-verification","ab-1043","coppa"],"license":"MIT","_id":"@a3api/node@0.1.1","maintainers":[{"name":"digital_arcadia","email":"connect@digital-arcadia.com"}],"dist":{"shasum":"dbf5062d63d1afdf02edf36754b5c8820020e87d","tarball":"https://registry.npmjs.org/@a3api/node/-/node-0.1.1.tgz","fileCount":7,"integrity":"sha512-7WZWyqlE3usT1BjKcNceJg0dRWs4kQa2xiqtLFi/W5P1HCh8RysMhJv0WjCiPmuXeBZTsCwVemABoIKfmx1ooQ==","signatures":[{"sig":"MEQCIE+kkAipd/Pf7EE6HK+nsbnqd2p9MpwXAgC1nFTGLIcwAiAatPdqTdiPi4RPRBlKK8j/OJAge+mTYc7EfdwHF1x9pA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43017},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"9157abd8eb48a85a780bf768728f0866c4c987c5","private":false,"scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest"},"_npmUser":{"name":"digital_arcadia","email":"connect@digital-arcadia.com"},"_npmVersion":"10.8.2","description":"Official Node.js client for the A3 Age Assurance API","directories":{},"sideEffects":false,"_nodeVersion":"20.10.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^2.0.0","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/node_0.1.1_1772327307426_0.7784851559005588","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@a3api/node","version":"0.1.2","description":"Official Node.js client for the A3 Age Assurance API","private":false,"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"engines":{"node":">=18"},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.7.2","vitest":"^2.0.0"},"keywords":["a3","age-assurance","age-verification","ab-1043","coppa"],"license":"MIT","_id":"@a3api/node@0.1.2","gitHead":"9157abd8eb48a85a780bf768728f0866c4c987c5","_nodeVersion":"20.10.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-HwDlg4Lwite9Nu4jFdRyYUkYUvJAh1tdsDF8CJRIHiCN9QXok6Z2ti39w63sWz4jp9dWDzjoiQQpmSdATHQ9mg==","shasum":"659342db17ddadc3edccc93ec45e016c3562afbf","tarball":"https://registry.npmjs.org/@a3api/node/-/node-0.1.2.tgz","fileCount":8,"unpackedSize":48559,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC8NRtZWdwkg/wM+iJxrRJs8aKWEb6129h/7KIm2cXafAIhAI4G7hqJdg5RtWEyKKPVnDp7gTc86YCvPyzMb6dykqQL"}]},"_npmUser":{"name":"digital_arcadia","email":"connect@digital-arcadia.com"},"directories":{},"maintainers":[{"name":"digital_arcadia","email":"connect@digital-arcadia.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node_0.1.2_1772332254631_0.15469451055349248"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-28T21:28:44.579Z","modified":"2026-03-01T02:30:54.908Z","0.1.0":"2026-02-28T21:28:44.826Z","0.1.1":"2026-03-01T01:08:27.571Z","0.1.2":"2026-03-01T02:30:54.772Z"},"license":"MIT","keywords":["a3","age-assurance","age-verification","ab-1043","coppa"],"description":"Official Node.js client for the A3 Age Assurance API","maintainers":[{"name":"digital_arcadia","email":"connect@digital-arcadia.com"}],"readme":"# @a3api/node\r\n\r\nOfficial Node.js client for the [Arcadia Age API (A3)](https://www.a3api.io). Handles request construction, typed responses, automatic retries, and structured error handling.\r\n\r\n- Full TypeScript types for requests and responses\r\n- Automatic retry with exponential backoff (429, 5xx, network errors)\r\n- Typed error classes for each failure mode\r\n- ESM + CJS + type declarations\r\n- Zero dependencies (uses native `fetch`)\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install @a3api/node\r\n```\r\n\r\nRequires Node.js 18 or later.\r\n\r\n## Quick Start\r\n\r\n```typescript\r\nimport { A3Client } from '@a3api/node';\r\n\r\nconst client = new A3Client({ apiKey: process.env.A3_API_KEY! });\r\n\r\nconst result = await client.assessAge({\r\n  os_signal: 'not-available',\r\n  user_country_code: 'US',\r\n  behavioral_metrics: {\r\n    avg_touch_precision: 0.72,\r\n    scroll_velocity: 1200,\r\n    form_completion_time_ms: 8500,\r\n  },\r\n});\r\n\r\nconsole.log(result.verdict);              // \"PROVISIONAL\"\r\nconsole.log(result.assessed_age_bracket); // \"18-plus\"\r\nconsole.log(result.confidence_score);     // 0.7\r\n```\r\n\r\n## Constructor Options\r\n\r\n```typescript\r\nconst client = new A3Client({\r\n  apiKey: 'your_api_key',     // Required\r\n  baseUrl: 'https://...',     // Default: https://api.a3api.io\r\n  timeout: 30_000,            // Default: 30000 (ms)\r\n  maxRetries: 2,              // Default: 2\r\n});\r\n```\r\n\r\n| Option | Type | Default | Description |\r\n|--------|------|---------|-------------|\r\n| `apiKey` | `string` | *required* | Your A3 API key |\r\n| `baseUrl` | `string` | `https://api.a3api.io` | API base URL |\r\n| `timeout` | `number` | `30000` | Request timeout in milliseconds |\r\n| `maxRetries` | `number` | `2` | Max retries for transient failures |\r\n\r\n## `client.assessAge(request)`\r\n\r\nSends signals to `POST /v1/assurance/assess-age` and returns the assessment.\r\n\r\n### Request\r\n\r\n| Field | Type | Required | Description |\r\n|-------|------|----------|-------------|\r\n| `os_signal` | `OsSignal` | Yes | `'under-13'` \\| `'13-15'` \\| `'16-17'` \\| `'18-plus'` \\| `'not-available'` |\r\n| `user_country_code` | `string` | Yes | ISO 3166-1 alpha-2 code (e.g., `'US'`) |\r\n| `behavioral_metrics` | `BehavioralMetrics` | No | Touch precision, scroll velocity, form timing, etc. |\r\n| `device_context` | `DeviceContext` | No | OS version, device model, accessibility settings |\r\n| `contextual_signals` | `ContextualSignals` | No | IP type, timezone offset, referrer category |\r\n| `account_longevity` | `AccountLongevity` | No | `{ account_age_days: number }` |\r\n| `input_complexity` | `InputComplexity` | No | Autocorrect rate, word complexity score |\r\n\r\n### Response\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| `verdict` | `Verdict` | `'CONSISTENT'` \\| `'OVERRIDE'` \\| `'REVIEW'` \\| `'PROVISIONAL'` |\r\n| `assessed_age_bracket` | `AgeBracket` | `'under-13'` \\| `'13-15'` \\| `'16-17'` \\| `'18-plus'` \\| `'undetermined'` |\r\n| `confidence_score` | `number` | 0–1 certainty in the assessed bracket (Pro/Scale plans only) |\r\n| `os_signal_age_bracket` | `AgeBracket` | OS signal echoed back |\r\n| `signal_overridden` | `boolean` | `true` when verdict is `OVERRIDE` |\r\n| `evidence_tags` | `string[]` | Audit trail of which signals influenced the verdict (Pro/Scale plans only) |\r\n| `verification_token` | `string` | HMAC-SHA256 signed cryptographic receipt — store in your logs |\r\n\r\n## Error Handling\r\n\r\nThe client throws typed errors you can catch individually:\r\n\r\n```typescript\r\nimport {\r\n  A3Client,\r\n  A3ValidationError,\r\n  A3AuthenticationError,\r\n  A3RateLimitError,\r\n  A3ConnectionError,\r\n} from '@a3api/node';\r\n\r\ntry {\r\n  const result = await client.assessAge(request);\r\n} catch (err) {\r\n  if (err instanceof A3ValidationError) {\r\n    // 400 — bad request body\r\n    console.error(err.validationErrors); // string[]\r\n  } else if (err instanceof A3AuthenticationError) {\r\n    // 401 — invalid API key\r\n  } else if (err instanceof A3RateLimitError) {\r\n    // 429 — rate limited (auto-retried, this means retries exhausted)\r\n    console.error(err.retryAfter); // ms until retry, if provided\r\n  } else if (err instanceof A3ConnectionError) {\r\n    // Network failure or timeout (auto-retried, retries exhausted)\r\n  }\r\n}\r\n```\r\n\r\n| Error Class | Status | Auto-Retried | Description |\r\n|-------------|--------|:------------:|-------------|\r\n| `A3ValidationError` | 400 | No | Request body failed validation |\r\n| `A3AuthenticationError` | 401 | No | Missing or invalid API key |\r\n| `A3RateLimitError` | 429 | Yes | Rate limit or quota exceeded |\r\n| `A3ApiError` | 5xx | Yes | Server error |\r\n| `A3ConnectionError` | — | Yes | Network failure or timeout |\r\n\r\n## Usage with Express\r\n\r\n```typescript\r\nimport express from 'express';\r\nimport { A3Client } from '@a3api/node';\r\n\r\nconst app = express();\r\napp.use(express.json());\r\n\r\nconst a3 = new A3Client({ apiKey: process.env.A3_API_KEY! });\r\n\r\napp.post('/api/assess-age', async (req, res) => {\r\n  const result = await a3.assessAge({\r\n    os_signal: 'not-available',\r\n    user_country_code: 'US',\r\n    ...req.body, // signals from @a3api/signals browser SDK\r\n  });\r\n\r\n  res.json({\r\n    verdict: result.verdict,\r\n    bracket: result.assessed_age_bracket,\r\n  });\r\n});\r\n```\r\n\r\n## Links\r\n\r\n- [Documentation](https://www.a3api.io/docs)\r\n- [Web Integration Guide](https://www.a3api.io/docs/integration/web-integration)\r\n- [API Reference](https://www.a3api.io/docs/integration/assess-age)\r\n- [Quickstart Project](https://github.com/a3api/a3-quickstart)\r\n- [Get an API Key](https://portal.a3api.io)\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}