Generate Your First API Key
Generate API Key via UI
- Log into PrivionGRC
- Go to API Keys in the main navigation
- Click + Generate API Key
- Configure your key settings (name, environment, permissions, rate limits)
- Click Generate Key and save it securely!
Note: API keys are shown only once during creation. Make sure to copy and store them securely.
Test Your API
Test 1: Submit a DSR
curl -X POST https://app.priviongrc.com/api/public/dsr \
-H "Content-Type: application/json" \
-H "X-API-Key: org_test_your_key_here" \
-d '{
"request_type": "access",
"data_subject_name": "Test User",
"data_subject_email": "test@example.com",
"description": "Test DSR submission"
}'Expected Response (201 Created):
{
"success": true,
"message": "DSR request created successfully",
"data": {
"id": "a1b2c3d4-...",
"request_type": "access",
"status": "pending",
"received_date": "2025-10-16T...",
"due_date": "2025-11-15T...",
"reference_number": "a1b2c3d4"
}
}Test 2: Check DSR Status
curl -X GET https://app.priviongrc.com/api/public/dsr/a1b2c3d4-... \ -H "X-API-Key: org_test_your_key_here"
Test 3: Create a DPIA Workflow
curl -X POST https://app.priviongrc.com/api/public/dpia \
-H "Content-Type: application/json" \
-H "X-API-Key: org_test_your_key_here" \
-d '{
"project_name": "Test Analytics System DPIA",
"description": "DPIA for testing analytics system",
"risk_level": "medium",
"status": "draft"
}'Test 4: Create a RoPA Record
curl -X POST https://app.priviongrc.com/api/public/ropa \
-H "Content-Type: application/json" \
-H "X-API-Key: org_test_your_key_here" \
-d '{
"name": "Test Processing Activity",
"description": "Test RoPA record creation",
"processing_purpose": "Testing API integration",
"legal_basis": "consent",
"status": "active"
}'Test 5: Rate Limiting
Make 11 requests quickly - the 11th should return:
{
"error": "Rate limit exceeded",
"message": "Maximum 10 requests per minute",
"retryAfter": 45
}Security Checklist
Before going to production:
Generate production API keys (start with
org_live_)Set appropriate rate limits (default: 60/min for production)
Configure IP whitelisting (optional but recommended)
Set expiration dates (recommend 90 days, rotate regularly)
Test error handling (invalid keys, rate limits, malformed requests)
Set up monitoring (API usage, error rates)
Document integration for your team
Never expose keys in client-side code
Common Integration Patterns
Pattern 1: Website Contact Form
// Backend API route (e.g., Next.js API route)
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { name, email, requestType } = req.body;
try {
const response = await fetch('https://app.priviongrc.com/api/public/dsr', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.PRIVIONGRC_API_KEY, // Server-side env var
},
body: JSON.stringify({
request_type: requestType,
data_subject_name: name,
data_subject_email: email,
source: 'website_form',
}),
});
const data = await response.json();
res.status(response.status).json(data);
} catch (error) {
res.status(500).json({ error: 'Failed to submit request' });
}
}Pattern 2: Python Client
# Partner system integration
import requests
import os
class PrivionGRCClient:
def __init__(self, api_key=None):
self.api_key = api_key or os.getenv('PRIVIONGRC_API_KEY')
self.base_url = 'https://app.priviongrc.com/api/public'
def submit_dsr(self, request_type, name, email, **kwargs):
"""Submit a DSR request"""
url = f'{self.base_url}/dsr'
headers = {
'Content-Type': 'application/json',
'X-API-Key': self.api_key
}
data = {
'request_type': request_type,
'data_subject_name': name,
'data_subject_email': email,
**kwargs
}
response = requests.post(url, json=data, headers=headers)
response.raise_for_status()
return response.json()
def check_dsr_status(self, dsr_id):
"""Check DSR status"""
url = f'{self.base_url}/dsr/{dsr_id}'
headers = {'X-API-Key': self.api_key}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
# Usage
client = PrivionGRCClient()
result = client.submit_dsr('access', 'John Doe', 'john@example.com')
print(f"DSR created: {result['data']['id']}")Troubleshooting
Issue: 401 Unauthorized
Causes:
- • Missing
X-API-Keyheader - • Invalid API key
- • Expired API key
- • Inactive API key
Solution:
- Check header is included:
X-API-Key: org_live_... - Verify key is active and not expired
- Check expiration date
- Generate a new key if needed
Issue: 429 Rate Limit Exceeded
Causes:
- • Too many requests in short time
- • Default limit: 10 requests/minute (test), 60/minute (production)
Solution:
- Respect
X-RateLimit-Remainingheader - Implement exponential backoff
- Request rate limit increase if needed
Issue: 403 Forbidden
Causes:
- • API key lacks required permission
- • IP not whitelisted (if configured)
Solution:
- Check API key permissions
- Update permissions:
{"dsr": ["create", "read"]} - Check IP whitelist configuration
You're Ready!
Your Public DSR Intake API is now live and ready to receive requests!
Next steps:
- Build the API Key management UI (Settings page)
- Add webhooks for status updates
- Create SDK libraries
- Add more public endpoints (RoPA read-only, etc.)
Need help? api@priviongrc.com