API Documentation
Simple REST API for secure, single-use approval links.
Quick Start
- 1. Sign in with GitHub to create a project
- 2. Generate an API key from your dashboard
- 3. Create an approval token with your desired actions
- 4. Share the link (email, chat, SMS)
- 5. Poll for the result in your automation
Security Model
Ottr uses magic-link security - the same model used by password reset emails. Security comes from the URL being cryptographically unguessable, not from a login session.
Try It Now
Replace YOUR_API_KEY with your write token from the dashboard.
1. Create an approval link
curl -X POST https://api.ottr.run/v1/approvals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"key_path": "demo/test", "value": "approved"}' 2. Check the value
curl https://api.ottr.run/v1/key/demo/test \
-H "Authorization: Bearer YOUR_API_KEY" 3. Open the approval URL and click the button. Check again - value changes.
Authentication
All API requests require Bearer token authentication:
Authorization: Bearer YOUR_API_KEYotw_* write key — read, write, create approvalsotr_* read key — read values onlyKey/Value Storage
/v1/key/{key_path}Get the current value of a key.
curl https://api.ottr.run/v1/key/deploy/prod \
-H "Authorization: Bearer YOUR_API_KEY" /v1/key/{key_path}/pendingCheck if there's a pending approval for a key.
{"pending": {"approval_id": "...", "expires_at": "..."}}/v1/key/{key_path}Set a key value directly. Requires write key.
curl -X PUT https://api.ottr.run/v1/key/deploy/prod \
-H "Authorization: Bearer YOUR_API_KEY" \
-d 'deployed' Approvals API
/v1/approvalsCreate a new approval token.
key_path key to update when token is usedvalue value to set (simple format)actions array of 1-3 actions (full format)ttl_seconds time to live (default: 600)initial_value set key to this before token creationinfo context shown on approval pageref_id reference ID for trackingcurl -X POST https://api.ottr.run/v1/approvals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key_path": "deploy/prod",
"actions": [
{"key": "approve", "value": "approved", "style": "primary"},
{"key": "reject", "value": "rejected", "style": "danger"}
],
"info": "Deploy v2.1.0 to production"
}' Response:
{
"approval_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"url": "https://ottr.run/a/01ARZ3NDEKTSV4RRFFQ69G5FAV",
"expires_at": "2025-01-01T12:30:00Z"
}/v1/approvals/{id}/invalidateInvalidate an approval before it expires. Returns 204.
Approval Status
Errors
All errors return JSON with an error field:
{"error": "invalid action key"}400 bad request401 unauthorized403 forbidden (expired or used)404 not found429 rate limited or lockedRate Limits
public
demo: 10/min
approval read: 60/min
approval action: 30/min
dashboard
read: 300/min
write: 60/min
automation (API key)
key read: 600/min
key write: 120/min
approval create: 60/min
Response headers:
X-RateLimit-Limit — max requests
X-RateLimit-Remaining — remaining
X-RateLimit-Reset — seconds until reset
Retry-After — seconds to wait (on 429)
Ready to get started?