Server SDK Reference

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 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.