Quick Start and API Docs
Base URL: https://veil-api.com · Start free on the pricing page or browse the public examples repo.
Start Here
If you just want to see Veil working, this is the fastest path:
- Get a free API key from the pricing page.
- Keep your existing upstream provider key.
- Point your OpenAI-compatible client at
https://veil-api.com/v1.
Minimal cURL test:
curl -X POST https://veil-api.com/v1/chat/completions \
-H "Authorization: Bearer your-veil-key" \
-H "x-upstream-key: your-openai-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Summarize: Customer John Smith (john@test.com, SSN 123-45-6789) wants a refund."}]
}'
The upstream model sees placeholders, while your app gets the restored response back.
Get a Key
All API requests require a Veil API key in the Authorization header:
Authorization: Bearer your-veil-api-key
The easiest path is the signup box on the pricing page. If you want to request a verification link via API, use:
curl -X POST https://veil-api.com/v1/keys/create \
-H "Content-Type: application/json" \
-d '{"email": "you@company.com"}'
This returns 202 Accepted and emails a one-time verification link. If you are building your own signup flow, exchange the token for a key with:
curl -X POST https://veil-api.com/v1/keys/verify \
-H "Content-Type: application/json" \
-d '{"token": "email-verification-token"}'
Authentication
Every request to Veil should include:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Your Veil API key |
x-upstream-key | Usually | Your LLM provider API key for proxy requests |
x-upstream-provider | No | Provider name if you want something other than openai |
Endpoints
POST /v1/chat/completions
OpenAI-compatible proxy. Strips PII from messages, forwards to your LLM provider, and restores PII in the response.
Headers: Authorization, x-upstream-key, and optionally x-upstream-provider.
Body: Standard OpenAI /v1/chat/completions request body. Supports stream: true.
Example:
curl -X POST https://veil-api.com/v1/chat/completions \
-H "Authorization: Bearer your-veil-key" \
-H "x-upstream-key: your-openai-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Summarize: Customer John Smith (john@test.com) wants a refund."}]
}'
Response: Standard OpenAI response with PII restored, plus a veil field:
{
"choices": [{"message": {"content": "John Smith requested a refund..."}}],
"veil": {
"entities_redacted": 2,
"entity_types": ["PERSON", "EMAIL_ADDRESS"]
}
}
POST /v1/redact
Standalone text redaction. No LLM call — just strip PII and return the result.
curl -X POST https://veil-api.com/v1/redact \
-H "Authorization: Bearer your-veil-key" \
-H "Content-Type: application/json" \
-d '{"text": "Contact Sarah at sarah@test.com, SSN 078-05-1120"}'
Response:
{
"redacted": "Contact <<VEIL_PERSON_a8f2c3d1e4f5>> at <<VEIL_EMAIL_ADDRESS_c3d1e4f5a8b2>>, SSN <<VEIL_US_SSN_9e7b1a2c3d4e>>",
"entities_found": 3,
"entity_types": ["PERSON", "EMAIL_ADDRESS", "US_SSN"]
}
GET /v1/usage
View your usage for the current billing period.
curl https://veil-api.com/v1/usage \ -H "Authorization: Bearer your-veil-key"
Response:
{
"period": "last_30_days",
"requests": 142,
"entities_redacted": 891,
"tier": "starter"
}
GET /v1/providers
List all supported LLM providers.
curl https://veil-api.com/v1/providers
GET /health
Health check. Returns {"status": "ok"}.
Using with the OpenAI SDK
If your app already uses an OpenAI-compatible client, integration is usually just a base URL plus two headers.
Python:
from openai import OpenAI
client = OpenAI(
api_key="your-openai-key",
base_url="https://veil-api.com/v1",
default_headers={
"Authorization": "Bearer your-veil-key",
"x-upstream-key": "your-openai-key",
}
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hi, I am Tom Ryan (tom@test.com)."}]
)
JavaScript:
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: 'https://veil-api.com/v1',
defaultHeaders: {
'Authorization': `Bearer ${process.env.VEIL_API_KEY}`,
'x-upstream-key': process.env.OPENAI_API_KEY,
}
});
Switching Providers
You do not need to switch off Veil to change model vendors. Set x-upstream-provider to route to any supported provider:
curl -X POST https://veil-api.com/v1/chat/completions \
-H "Authorization: Bearer your-veil-key" \
-H "x-upstream-key: your-together-key" \
-H "x-upstream-provider: together" \
-H "Content-Type: application/json" \
-d '{"model": "meta-llama/Llama-3-8b-chat-hf", "messages": [...]}'
Entity Types
Veil detects 79+ entity types across 18 countries:
- Global: PERSON, EMAIL_ADDRESS, PHONE_NUMBER, CREDIT_CARD, CRYPTO, IP_ADDRESS, MAC_ADDRESS, IBAN_CODE, LOCATION, MEDICAL_LICENSE
- USA: US_SSN, US_PASSPORT, US_DRIVER_LICENSE, US_BANK_NUMBER, US_ITIN, US_MBI, US_NPI, ABA_ROUTING_NUMBER
- UK: UK_NHS, UK_NINO, UK_PASSPORT, UK_POSTCODE, UK_VEHICLE_REGISTRATION
- Germany: DE_TAX_ID, DE_PASSPORT, DE_ID_CARD, DE_SOCIAL_SECURITY, DE_HEALTH_INSURANCE, DE_KFZ, DE_VAT_ID, DE_LANR, DE_BSNR, DE_FUEHRERSCHEIN
- More: ES, IT, PL, SG, AU, IN, FI, KR, NG, SE, TH, CA, BR, FR, MX
- Secrets: API_KEY, DATABASE_URL, BEARER_TOKEN, PASSWORD
- Crypto: CRYPTO_WALLET (Ethereum, Bitcoin, Litecoin, Monero)
- Context PII: DATE_OF_BIRTH, CVV, VIN, IMEI, US_EIN, SWIFT_BIC, GEO_COORDINATE
Allowlisting
Skip specific entity types or values using headers:
curl -X POST https://veil-api.com/v1/chat/completions \
-H "Authorization: Bearer your-veil-key" \
-H "x-upstream-key: your-openai-key" \
-H "x-veil-allow: PERSON,LOCATION" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4o-mini", "messages": [...]}'
Headers:
| Header | Description |
|---|---|
x-veil-allow | Comma-separated entity types to skip (e.g., PERSON,LOCATION) |
x-veil-allow-values | Comma-separated specific strings to skip (e.g., Acme Corp,support@acme.com) |
Audit Log
View your recent redaction history for compliance.
curl https://veil-api.com/v1/audit \ -H "Authorization: Bearer your-veil-key"
Returns up to 100 entries with timestamps, entity counts, types, and model info.
Plans
| Tier | Requests/month | Price |
|---|---|---|
| Free | 100 | $0 |
| Starter | 10,000 | $49/mo |
| Growth | 100,000 | $149/mo |
| Enterprise | 1,000,000+ | $499/mo |
Start on the free tier, then upgrade in place when you are ready to put real traffic through it.
Error Reference
All errors return JSON with a detail field:
| Status | Meaning | Example detail |
|---|---|---|
400 | Bad request | "x-upstream-key header is required", "Unsupported provider: xyz", "Valid email address required", "Invalid or expired verification token" |
401 | Auth failed | "Missing Authorization header", "Invalid API key" |
409 | Conflict | "This email already has an account" (after successful email verification) |
429 | Rate limited | "Monthly request limit reached for free tier (100 requests)" |
Upstream LLM errors are sanitized — you'll see "Upstream provider returned 4xx" without the raw provider error body.
Privacy
Veil never stores your message content or PII values. Only metadata (timestamps, entity counts, entity types) is logged. See our full Privacy Policy.