{"_id":"@abxy/foil-server","_rev":"3-be057c12116b728b59fbee5f83fc73a9","name":"@abxy/foil-server","dist-tags":{"latest":"0.2.6"},"versions":{"0.2.4":{"name":"@abxy/foil-server","version":"0.2.4","license":"MIT","_id":"@abxy/foil-server@0.2.4","maintainers":[{"name":"alain","email":"me@alainmeier.com"}],"homepage":"https://github.com/abxy-labs/foil-server-node#readme","bugs":{"url":"https://github.com/abxy-labs/foil-server-node/issues"},"dist":{"shasum":"30154661cd2a5eced2b141c524ca20502e73685c","tarball":"https://registry.npmjs.org/@abxy/foil-server/-/foil-server-0.2.4.tgz","fileCount":55,"integrity":"sha512-hHnf0J4wTuOO/D8jyDzONwCnX9m8sxFDokfSDMPz1vyh9M3Ku1N33609KU7wguAuJqI0RLF3uUmFMd+aOrQFzw==","signatures":[{"sig":"MEQCIESG2fUIqSWvmpDqf4vAT16c8j/utoyizLEfmkppfVw3AiBzGLDbwcNAjK+2oxcH9kZwLPPgLFQKz8ceI42XDCpa9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":987117},"main":"./dist/index.cjs","type":"module","_from":"file:artifacts/abxy-foil-server-0.2.4.tgz","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"}},"scripts":{"test":"vitest run tests/client.test.ts tests/contract.test.ts tests/sealed-token.test.ts tests/gate-delivery.test.ts","build":"tsup && tsc -p tsconfig.build.json","check":"npm run typecheck && npm run test && npm run build && npm run test:packaging","test:live":"vitest run tests/live.test.ts","typecheck":"tsc --noEmit","test:packaging":"node ./scripts/check-packaging.mjs","check:spec-sync":"bash ./scripts/check-spec-sync.sh"},"_npmUser":{"name":"alain","email":"me@alainmeier.com"},"_resolved":"/home/runner/work/foil-server-node/foil-server-node/artifacts/abxy-foil-server-0.2.4.tgz","_integrity":"sha512-hHnf0J4wTuOO/D8jyDzONwCnX9m8sxFDokfSDMPz1vyh9M3Ku1N33609KU7wguAuJqI0RLF3uUmFMd+aOrQFzw==","repository":{"url":"git+https://github.com/abxy-labs/foil-server-node.git","type":"git"},"_npmVersion":"11.12.1","description":"Official Foil Node server SDK","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^4.1.0","typescript":"^6.0.3","@types/node":"^24.6.1"},"_npmOperationalInternal":{"tmp":"tmp/foil-server_0.2.4_1779488480898_0.5497121084298127","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@abxy/foil-server","version":"0.2.5","license":"MIT","_id":"@abxy/foil-server@0.2.5","maintainers":[{"name":"alain","email":"me@alainmeier.com"}],"homepage":"https://github.com/abxy-labs/foil-server-node#readme","bugs":{"url":"https://github.com/abxy-labs/foil-server-node/issues"},"dist":{"shasum":"178e4e6125527b576388d7b1e8ff7628a1f803a1","tarball":"https://registry.npmjs.org/@abxy/foil-server/-/foil-server-0.2.5.tgz","fileCount":55,"integrity":"sha512-PJiIPjKfzaMGtERETec4ekACMNVhw6RCQmaJt8LJNtLftLLysUeFY0sEme4ec5lvU1MljjmPPsGG6+1YzGX7+A==","signatures":[{"sig":"MEUCIQChMArzWWqSrqrD28vEwBCBQbYj1gQ8C6tzaZBuFejhpwIgSs7A413TsEfCEME2WKJTdgpP34x3tijojoW4XBjR0P4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abxy%2ffoil-server@0.2.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":996337},"main":"./dist/index.cjs","type":"module","_from":"file:artifacts/abxy-foil-server-0.2.5.tgz","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"}},"scripts":{"test":"vitest run tests/client.test.ts tests/contract.test.ts tests/sealed-token.test.ts tests/gate-delivery.test.ts","build":"tsup && tsc -p tsconfig.build.json","check":"npm run typecheck && npm run test && npm run build && npm run test:packaging","test:live":"vitest run tests/live.test.ts","typecheck":"tsc --noEmit","test:packaging":"node ./scripts/check-packaging.mjs","check:spec-sync":"bash ./scripts/check-spec-sync.sh"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1c24b148-402d-4cab-aae9-af3edeba353e"}},"_resolved":"/home/runner/work/foil-server-node/foil-server-node/artifacts/abxy-foil-server-0.2.5.tgz","_integrity":"sha512-PJiIPjKfzaMGtERETec4ekACMNVhw6RCQmaJt8LJNtLftLLysUeFY0sEme4ec5lvU1MljjmPPsGG6+1YzGX7+A==","repository":{"url":"git+https://github.com/abxy-labs/foil-server-node.git","type":"git"},"_npmVersion":"11.16.0","description":"Official Foil Node server SDK","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^4.1.0","typescript":"^6.0.3","@types/node":"^24.6.1"},"_npmOperationalInternal":{"tmp":"tmp/foil-server_0.2.5_1784571278582_0.2283188448028004","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"@abxy/foil-server","version":"0.2.6","description":"Official Foil Node server SDK","license":"MIT","repository":{"type":"git","url":"git+https://github.com/abxy-labs/foil-server-node.git"},"homepage":"https://github.com/abxy-labs/foil-server-node#readme","bugs":{"url":"https://github.com/abxy-labs/foil-server-node/issues"},"type":"module","sideEffects":false,"engines":{"node":">=18"},"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"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsup && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit","test":"vitest run tests/client.test.ts tests/contract.test.ts tests/sealed-token.test.ts tests/gate-delivery.test.ts","test:live":"vitest run tests/live.test.ts","check:spec-sync":"bash ./scripts/check-spec-sync.sh","test:packaging":"node ./scripts/check-packaging.mjs","check":"npm run typecheck && npm run test && npm run build && npm run test:packaging"},"devDependencies":{"@types/node":"^24.6.1","tsup":"^8.5.0","typescript":"^6.0.3","vitest":"^4.1.0"},"_id":"@abxy/foil-server@0.2.6","_integrity":"sha512-0mDWONTV296bTyObTpAoZhdLwT9yoXBB1UZN3s9dlQdj29AkEhdSAMVHLOHfkdUZetPKeUEfD0u+NrvcnakvxQ==","_resolved":"/home/runner/work/foil-server-node/foil-server-node/artifacts/abxy-foil-server-0.2.6.tgz","_from":"file:artifacts/abxy-foil-server-0.2.6.tgz","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-0mDWONTV296bTyObTpAoZhdLwT9yoXBB1UZN3s9dlQdj29AkEhdSAMVHLOHfkdUZetPKeUEfD0u+NrvcnakvxQ==","shasum":"2fe003136c23c20edf17aca34b48e6bb4d11eb29","tarball":"https://registry.npmjs.org/@abxy/foil-server/-/foil-server-0.2.6.tgz","fileCount":56,"unpackedSize":1020117,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@abxy%2ffoil-server@0.2.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDmfDxGAkULdy3kTi56TE0QBHFyifvZV1gbXPnx62fGsAIgKv788P4NYnAKqgSFeLHcIR2pKxTuEaITq8bH2oN5dY8="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1c24b148-402d-4cab-aae9-af3edeba353e"}},"directories":{},"maintainers":[{"name":"alain","email":"me@alainmeier.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/foil-server_0.2.6_1784575753190_0.30134614565851625"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-22T22:21:20.710Z","modified":"2026-07-20T19:29:13.652Z","0.2.4":"2026-05-22T22:21:21.057Z","0.2.5":"2026-07-20T18:14:38.766Z","0.2.6":"2026-07-20T19:29:13.320Z"},"bugs":{"url":"https://github.com/abxy-labs/foil-server-node/issues"},"license":"MIT","homepage":"https://github.com/abxy-labs/foil-server-node#readme","repository":{"type":"git","url":"git+https://github.com/abxy-labs/foil-server-node.git"},"description":"Official Foil Node server SDK","maintainers":[{"name":"alain","email":"me@alainmeier.com"}],"readme":"# Foil Node Library\n\n![Preview](https://img.shields.io/badge/status-preview-111827)\n![Node 18+](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js&logoColor=white)\n![License: MIT](https://img.shields.io/badge/license-MIT-0f766e.svg)\n\nThe Foil Node library provides convenient access to the Foil API from applications running in Node.js. It includes a typed client for Sessions, Fingerprints, Organizations, organization API key management, sealed token verification, Gate, and Gate delivery/webhook helpers.\n\nThe library also provides:\n\n- a fast configuration path using `FOIL_SECRET_KEY`\n- helpers for cursor-based pagination\n- structured API errors and built-in sealed token verification\n- webhook endpoint management, test sends, and event delivery history\n- public, bearer-token, and secret-key auth modes for Gate flows\n- Gate delivery/webhook helpers\n\n## Documentation\n\nSee the [Foil docs](https://usefoil.com/docs) and [API reference](https://usefoil.com/docs/api-reference/introduction).\n\n## Installation\n\nYou don't need this source code unless you want to modify the package. If you just want to use the package, run:\n\n```bash\nnpm install @abxy/foil-server\n```\n\n## Requirements\n\n- Node 18+\n\n## Usage\n\nUse `FOIL_SECRET_KEY` or an explicit `secretKey` for core detect APIs. For public or bearer-auth Gate flows, the client can also be constructed without a secret key:\n\n```ts\nimport { Foil } from \"@abxy/foil-server\";\n\nconst client = new Foil({\n  secretKey: process.env.FOIL_SECRET_KEY,\n});\n\nconst page = await client.sessions.list({ verdict: \"bot\", limit: 25 });\nconst session = await client.sessions.get(\"sid_123\");\nawait client.sessions.attachClientUser(\"sid_123\", \"user_123\");\nawait client.sessions.clearClientUser(\"sid_123\");\n\nconsole.log(page.has_more, page.next_cursor);\nconsole.log(session.decision.risk_score, session.highlights[0]?.summary);\n```\n\n### Sealed token verification\n\n```ts\nimport { safeVerifyFoilToken } from \"@abxy/foil-server\";\n\nconst result = safeVerifyFoilToken(\n  sealedToken,\n  process.env.FOIL_SECRET_KEY,\n);\n\nif (!result.ok) {\n  console.error(result.error);\n  return;\n}\n\nconsole.log(result.data.decision.verdict, result.data.decision.risk_score);\n```\n\n### Pagination\n\n```ts\nfor await (const session of client.sessions.iter({ search: \"signup\" })) {\n  console.log(session.id, session.latest_decision.verdict);\n}\n```\n\n### Fingerprints\n\n```ts\nconst page = await client.fingerprints.list({ sort: \"seen_count\" });\nconst fingerprint = await client.fingerprints.get(\"vid_123\");\n\nconsole.log(fingerprint.lifecycle.last_seen_at);\n```\n\n### Organizations\n\n```ts\nconst organization = await client.organizations.get(\"org_123\");\nconst updated = await client.organizations.update(\"org_123\", { name: \"New Name\" });\n```\n\n### Organization API keys\n\n```ts\nconst created = await client.organizations.apiKeys.create(\"org_123\", {\n  name: \"Production\",\n  type: \"secret\",\n  environment: \"live\",\n  scopes: [\"sessions:list\", \"sessions:read\"],\n});\n\nawait client.organizations.apiKeys.revoke(\"org_123\", created.id);\n```\n\n### Webhooks\n\n```ts\nconst endpoint = await client.webhooks.createEndpoint(\"org_123\", {\n  name: \"Production alerts\",\n  url: \"https://example.com/foil/webhook\",\n  event_types: [\"session.result.persisted\", \"gate.session.approved\"],\n});\n\nconst events = await client.webhooks.listEvents(\"org_123\", {\n  endpoint_id: endpoint.id,\n  type: \"session.result.persisted\",\n});\n\nconsole.log(events.items[0]?.webhook_deliveries[0]?.status);\n```\n\n### Gate APIs\n\n```ts\nconst client = new Foil();\n\nconst services = await client.gate.registry.list();\nconst session = await client.gate.sessions.create({\n  service_id: \"foil\",\n  account_name: \"my-project\",\n  delivery: createDeliveryKeyPair().delivery,\n});\n\nconsole.log(services[0]?.id, session.consent_url);\n```\n\n### Gate delivery and webhook helpers\n\n```ts\nimport {\n  createDeliveryKeyPair,\n  createGateApprovedWebhookResponse,\n  decryptGateDeliveryEnvelope,\n  verifyGateWebhookSignature,\n} from \"@abxy/foil-server\";\n\nconst keyPair = createDeliveryKeyPair();\nconst response = createGateApprovedWebhookResponse({\n  delivery: keyPair.delivery,\n  outputs: {\n    FOIL_PUBLISHABLE_KEY: \"pk_live_...\",\n    FOIL_SECRET_KEY: \"sk_live_...\",\n  },\n});\n\nconst payload = decryptGateDeliveryEnvelope(keyPair.privateKey, response.encrypted_delivery);\nconsole.log(payload.outputs.FOIL_SECRET_KEY);\n\nconsole.log(verifyGateWebhookSignature({\n  secret: \"whsec_test\",\n  timestamp: \"1735776000\",\n  rawBody: \"{\\\"event\\\":\\\"gate.session.approved\\\"}\",\n  signature: \"…\",\n}));\n```\n\n### Error handling\n\n```ts\nimport { FoilApiError } from \"@abxy/foil-server\";\n\ntry {\n  await client.sessions.list({ limit: 999 });\n} catch (error) {\n  if (error instanceof FoilApiError) {\n    console.error(error.status, error.code, error.message);\n  }\n}\n```\n\n## Support\n\nIf you need help integrating Foil, start with [usefoil.com/docs](https://usefoil.com/docs).\n","readmeFilename":"README.md"}