Claude Code skill pack for Persona (18 skills)
Installation
Open Claude Code and run this command:
/plugin install persona-pack@claude-code-plugins-plus
Use --global to install for all projects, or --project for current project only.
Skills (18)
CI/CD pipeline for Persona integrations with sandbox API testing.
persona ci integration | sed 's/\b\(.\)/\u\1/g'
Overview
GitHub Actions with sandbox credentials, webhook simulation, integration tests.
Prerequisites
- Completed
persona-install-authsetup - Valid Persona API key (sandbox or production)
Instructions
Step 1: Implementation
import os, requests
HEADERS = {
"Authorization": f"Bearer {os.environ['PERSONA_API_KEY']}",
"Persona-Version": "2023-01-05",
}
BASE = "https://withpersona.com/api/v1"
# CI/CD pipeline for Persona integrations with sandbox API testing
resp = requests.get(f"{BASE}/inquiries?page[size]=10", headers=HEADERS)
resp.raise_for_status()
inquiries = resp.json()["data"]
for inq in inquiries:
print(f" {inq['id']}: {inq['attributes']['status']}")
Output
- GitHub Actions with sandbox credentials, webhook simulation, integration tests.
Error Handling
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid API key | Check PERSONAAPIKEY |
| 429 Rate Limited | Too many requests | Implement backoff |
| 404 Not Found | Wrong resource ID | Verify ID format |
Resources
Next Steps
See related Persona skills for more workflows.
Fix top Persona API errors: 401, 422, webhook signature failures, inquiry state issues.
persona common errors | sed 's/\b\(.\)/\u\1/g'
Overview
401 invalid key, 422 invalid template, webhook HMAC mismatch, inquiry already completed, rate limit 429.
Prerequisites
- Completed
persona-install-authsetup - Valid Persona API key (sandbox or production)
Instructions
Error 1: 401 Unauthorized
{"errors":[{"status":"401","title":"Not Authorized"}]}
Fix: Verify API key starts with personasandbox or personaproduction. Check Authorization: Bearer header format.
Error 2: 422 Invalid Inquiry Template
{"errors":[{"status":"422","title":"Invalid inquiry-template-id"}]}
Fix: Verify template ID format is itmpl_*. Templates are environment-specific (sandbox templates only work with sandbox keys).
Error 3: Webhook Signature Mismatch
HMAC verification failed — expected abc123, got def456
Fix: Ensure you're using the raw request body (not parsed JSON) for HMAC computation. Use express.raw() middleware.
Error 4: 429 Rate Limited
{"errors":[{"status":"429","title":"Rate limit exceeded"}]}
Fix: Implement exponential backoff. Check Retry-After header. See persona-rate-limits.
Error 5: Inquiry Already Completed
{"errors":[{"status":"409","title":"Inquiry is already in a terminal state"}]}
Fix: Check inquiry status before attempting operations. Use the resume endpoint only for created or pending inquiries.
Error 6: 404 Inquiry Not Found
{"errors":[{"status":"404","title":"Not Found"}]}
Fix: Verify inquiry ID format is inq_*. Sandbox inquiries are not accessible with production keys.
Output
- Error identified from API response
- Targeted fix applied
- Verified resolution
Error Handling
| HTTP Code | Meaning | Retryable | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 400 | Bad request | No | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 401 | Invalid API key | No — fix key | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 404 | Resource not found | No | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 409 | Conflict (terminal state) | No | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 422 | Validation error | No — fix request | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 429 | Rate limited | Yes | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 500+ | <
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid API key | Check PERSONAAPIKEY |
| 429 Rate Limited | Too many requests | Implement backoff |
| 404 Not Found | Wrong resource ID | Verify ID format |
Resources
Next Steps
See related Persona skills for more workflows.
Collect Persona diagnostic info: inquiry IDs, API responses, webhook logs.
persona debug bundle | sed 's/\b\(.\)/\u\1/g'
Overview
Gather inquiry state, verification results, webhook delivery logs, API connectivity test.
Prerequisites
- Completed
persona-install-authsetup - Valid Persona API key (sandbox or production)
Instructions
Step 1: Implementation
import os, requests
HEADERS = {
"Authorization": f"Bearer {os.environ['PERSONA_API_KEY']}",
"Persona-Version": "2023-01-05",
}
BASE = "https://withpersona.com/api/v1"
# Collect Persona diagnostic info: inquiry IDs, API responses, webhook logs
resp = requests.get(f"{BASE}/inquiries?page[size]=10", headers=HEADERS)
resp.raise_for_status()
inquiries = resp.json()["data"]
for inq in inquiries:
print(f" {inq['id']}: {inq['attributes']['status']}")
Output
- Gather inquiry state, verification results, webhook delivery logs, API connectivity test.
Error Handling
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid API key | Check PERSONAAPIKEY |
| 429 Rate Limited | Too many requests | Implement backoff |
| 404 Not Found | Wrong resource ID | Verify ID format |
Resources
Next Steps
See related Persona skills for more workflows.
Deploy Persona verification service to cloud platforms.
persona deploy integration | sed 's/\b\(.\)/\u\1/g'
Overview
Dockerfile, Cloud Run deployment, secrets management, health checks.
Prerequisites
- Completed
persona-install-authsetup - Valid Persona API key (sandbox or production)
Instructions
Step 1: Implementation
import os, requests
HEADERS = {
"Authorization": f"Bearer {os.environ['PERSONA_API_KEY']}",
"Persona-Version": "2023-01-05",
}
BASE = "https://withpersona.com/api/v1"
# Deploy Persona verification service to cloud platforms
resp = requests.get(f"{BASE}/inquiries?page[size]=10", headers=HEADERS)
resp.raise_for_status()
inquiries = resp.json()["data"]
for inq in inquiries:
print(f" {inq['id']}: {inq['attributes']['status']}")
Output
- Dockerfile, Cloud Run deployment, secrets management, health checks.
Error Handling
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid API key | Check PERSONAAPIKEY |
| 429 Rate Limited | Too many requests | Implement backoff |
| 404 Not Found | Wrong resource ID | Verify ID format |
Resources
Next Steps
See related Persona skills for more workflows.
Create your first Persona identity verification inquiry and check its status.
Persona Hello World
Overview
Create a Persona inquiry, generate an embed URL for the verification flow, and poll for the inquiry status. Uses the real Persona REST API with sandbox credentials.
Prerequisites
- Completed
persona-install-authsetup - An Inquiry Template ID from the Persona Dashboard (format:
itmpl_*)
Instructions
Step 1: Create an Inquiry
import os, requests
API_KEY = os.environ["PERSONA_API_KEY"]
BASE = "https://withpersona.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Persona-Version": "2023-01-05",
"Content-Type": "application/json",
}
# Create a new inquiry from a template
resp = requests.post(f"{BASE}/inquiries", headers=HEADERS, json={
"data": {
"attributes": {
"inquiry-template-id": "itmpl_YOUR_TEMPLATE_ID",
"reference-id": "user-12345", # Your internal user ID
}
}
})
resp.raise_for_status()
inquiry = resp.json()["data"]
inquiry_id = inquiry["id"]
status = inquiry["attributes"]["status"]
print(f"Inquiry created: {inquiry_id} (status: {status})")
Step 2: Get the Verification URL
# The inquiry includes a session token for the embedded flow
session_token = inquiry["attributes"].get("session-token")
if session_token:
# Option A: Hosted flow (redirect user to Persona)
hosted_url = f"https://withpersona.com/verify?inquiry-id={inquiry_id}&session-token={session_token}"
print(f"Send user to: {hosted_url}")
# Option B: Embedded flow (JavaScript SDK in your page)
print(f"Embed with: Persona.Client({{ templateId: 'itmpl_...', inquiryId: '{inquiry_id}' }})")
Step 3: Poll for Completion
import time
for _ in range(30): # Poll for up to 5 minutes
resp = requests.get(f"{BASE}/inquiries/{inquiry_id}", headers=HEADERS)
resp.raise_for_status()
status = resp.json()["data"]["attributes"]["status"]
print(f" Status: {status}")
if status in ("completed", "approved", "declined"):
break
time.sleep(10)
# Get verification details
if status == "completed":
verifications = resp.json()["data"]["relationships"]["verifications"]["data"]
for v in verifications:
print(f" Verification: {v['type']} — {v['id']}")
Step 4: Retrieve Verification Results
# Get detailed verification result
verification_id =Configure Persona API authentication with sandbox and production API keys.
Persona Install & Auth
Overview
Set up Persona API authentication. Persona uses Bearer token auth with environment-prefixed API keys (personasandbox for testing, personaproduction for live). No SDK required -- direct REST API calls with any HTTP client.
Prerequisites
- Persona account at withpersona.com
- At least one Inquiry Template configured in the Persona Dashboard
- Node.js 18+ or Python 3.9+
Instructions
Step 1: Get API Keys
1. Log into dashboard.withpersona.com
2. Go to Settings > API Keys
3. Copy your sandbox key (starts with persona_sandbox_)
4. For production: copy production key (starts with persona_production_)
Step 2: Configure Environment
# .env — never commit
PERSONA_API_KEY=persona_sandbox_xxxxxxxxxxxxxxxxxxxxxxxx
PERSONA_API_VERSION=2023-01-05
# .gitignore
echo '.env' >> .gitignore
Step 3: Install HTTP Client
set -euo pipefail
# Node.js
npm install axios dotenv
# Python
pip install requests python-dotenv
Step 4: Verify Connection (Node.js)
import axios from 'axios';
const persona = axios.create({
baseURL: 'https://withpersona.com/api/v1',
headers: {
'Authorization': `Bearer ${process.env.PERSONA_API_KEY}`,
'Persona-Version': process.env.PERSONA_API_VERSION || '2023-01-05',
'Content-Type': 'application/json',
},
});
async function verify() {
const { data } = await persona.get('/inquiries?page[size]=1');
console.log(`Connected! Found ${data.data.length} inquiry(ies).`);
}
verify().catch(console.error);
Step 5: Verify Connection (Python)
import os, requests
from dotenv import load_dotenv
load_dotenv()
headers = {
"Authorization": f"Bearer {os.environ['PERSONA_API_KEY']}",
"Persona-Version": os.environ.get("PERSONA_API_VERSION", "2023-01-05"),
}
resp = requests.get("https://withpersona.com/api/v1/inquiries?page[size]=1", headers=headers)
resp.raise_for_status()
print(f"Connected! Status: {resp.status_code}")
Output
- API key configured and verified
- HTTP client set up with correct headers
- Successful test call to Persona API
Error Handling
| Error | Cause | Solution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
401 Unauthorized |
Invalid or expired API key | Verify key in Dashboard > Settings > API Keys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
403 Forbidden |
Key doesn't match environment | Use persona
|