For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Help CenterOpenAPI SpecStatus
OverviewInquiriesTransactionsRelaysAPI ReferenceChangelog
OverviewInquiriesTransactionsRelaysAPI ReferenceChangelog
  • Overview
    • Relay Overview
    • Getting Started
  • Widget
    • Usage
  • Integration Methods
    • Server SDK
  • References
    • Relay Widget SDK
    • Server SDK
    • Gateway Service
    • API
    • Schemas
LogoLogo
Help CenterOpenAPI SpecStatus
On this page
  • Installation
  • Constructor
  • Persona
  • Methods
  • create
  • issuePrivacyPass
  • generateClaim
  • Error handling
References

Server SDK Reference

Was this page helpful?
Previous

Gateway Service Reference

Next
Built with

This page documents the full server-side API for the Persona Relay SDK for Node.js.

Installation

Available on npm: @persona/relay-sdk-node

npm
yarn
$npm install @persona/relay-sdk-node

Constructor

Persona

1import Persona from '@persona/relay-sdk-node';
2
3const persona = new Persona({ apiKey: <your_api_key> });

Arguments

OptionTypeRequiredDescription
apiKeystringfalseYour Persona API key. Not required for relay session creation (relays.create), but may be required for other Persona API calls

Methods

Relay methods are available on the persona.relays namespace.

create

Creates a Persona relay session. No API key required.

1const session = await persona.relays.create({
2 claimType: 'age_18_plus_verified',
3 encryptionKeyPem: '<your_public_key_pem>',
4});

Arguments

FieldTypeRequiredDescription
claimTypestringtrueThe claim type to evaluate. See Claim types for the full list
encryptionKeyPemstring | nulltruePEM-encoded RSA public key. If provided, Persona encrypts the claim payload on redemption. Pass null to receive plaintext JSON

Returns

FieldTypeDescription
relayTokenstringIdentifies the relay session. Pass to subsequent issuePrivacyPass and generateClaim calls
relaySecretstringAuthenticates your server’s calls on this session. Keep server-side — never expose to the client
relaySessionAccessTokenstringShort-lived token passed to the client-side widget via your server

issuePrivacyPass

Runs the full blind RSA issuance flow and returns a Privacy Pass token. The SDK handles all cryptography internally.

How does this work?
Curious how the Privacy Pass protocol works under the hood? See Privacy Pass Protocol for a full walkthrough — relevant if you’re implementing this yourself without the SDK.
1const { privacyPassToken } = await persona.relays.issuePrivacyPass({
2 relayToken: session.relayToken,
3 relaySecret: session.relaySecret,
4});

Arguments

FieldTypeRequiredDescription
relayTokenstringtrueThe relay token from persona.relays.create
relaySecretstringtrueThe relay secret from persona.relays.create

Returns

FieldTypeDescription
privacyPassTokenstringThe issued Privacy Pass token. Hold this server-side and pass to generateClaim once the user completes verification

generateClaim

Redeems the Privacy Pass token against Persona and returns the claim payload.

1const claim = await persona.relays.generateClaim({
2 privacyPassToken,
3 relayToken: session.relayToken,
4 relaySecret: session.relaySecret,
5});

If you created the relay session with an encryptionKeyPem, claimPayload will be a base64-encoded RSA-OAEP ciphertext. Decrypt it with your corresponding private key.

Arguments

FieldTypeRequiredDescription
privacyPassTokenstringtrueThe Privacy Pass token from persona.relays.issuePrivacyPass
relayTokenstringtrueThe relay token from persona.relays.create
relaySecretstringtrueThe relay secret from persona.relays.create

Returns

FieldTypeDescription
claimPayloadstringPlaintext JSON claim result, or base64-encoded RSA-OAEP ciphertext if encryptionKeyPem was set on session creation. See Claim payload schema
tokenConsumedbooleanWhether the Privacy Pass token was consumed by this redemption. A consumed token cannot be redeemed again

Error handling

All Persona API errors and network failures throw a subtype of PersonaError.

1import { PersonaError, BadRequestError, RateLimitedError } from '@persona/relay-sdk-node';
2
3try {
4 const claim = await persona.relays.generateClaim({ ... });
5} catch (err) {
6 if (err instanceof RateLimitedError) {
7 // retry with backoff
8 } else if (err instanceof PersonaError) {
9 console.error(err.statusCode, err.title, err.details);
10 }
11}

See PersonaError for the full error class definition.