Authentication
Every API request must include your API key in the Authorization header as a Bearer token.
curl https://api.firsthandapi.com/v1/jobs \
-H "Authorization: Bearer fh_live_sk_abc123..."API Key Types
FirstHandAPI uses two types of API keys, distinguished by prefix:
| Prefix | Environment | Charges Real Money? | AI Scoring |
|---|---|---|---|
fh_live_ | Production | Yes | Real Claude Vision + Whisper |
fh_test_ | Sandbox | No | Synthetic (always 4 stars) |
Switch between environments by changing your API key — no code changes needed.
Getting Your API Key
- Sign up at dashboard.firsthandapi.com
- Navigate to API Keys in the sidebar
- Click Create Key and select your scopes
- Copy the key immediately — it’s only shown once
Or programmatically:
curl -X POST https://api.firsthandapi.com/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{"name": "My Organization", "email": "dev@example.com"}'Response:
{
"organization_id": "org_01HV...",
"api_key": "fh_live_sk_abc123...",
"credits_cents": 500
}Every new account receives $2.50 in free credits.
Scopes
API keys have granular scopes that control what they can access:
| Scope | Allows |
|---|---|
jobs:read | List and get jobs, files, submissions |
jobs:write | Create, cancel, and rate jobs |
webhooks:read | List webhook endpoints |
webhooks:write | Create, update, delete webhook endpoints |
keys:manage | Create and revoke API keys |
billing:read | View credit balance and transactions |
billing:write | Purchase credits |
audit:read | View audit event log |
usage:read | View organization settings |
Dashboard session keys include all scopes. Keys created via the API can be scoped to specific permissions.
Key Rotation
To rotate a key without downtime:
- Create a new key with the same scopes
- Update your application to use the new key
- Verify the new key works
- Revoke the old key via
DELETE /v1/api_keys/:id
Security Best Practices
- Never expose API keys in client-side code — keep them server-side only
- Use environment variables — don’t hardcode keys in source code
- Use minimum necessary scopes — a key that only reads jobs doesn’t need
billing:write - Rotate keys regularly — especially after team member departures
- Use sandbox keys for testing — never test with production keys
SDK Authentication
// TypeScript
import { FirstHandClient } from '@firsthandapi/sdk';
const client = new FirstHandClient({ apiKey: process.env.FIRSTHAND_API_KEY });# Python
from firsthandapi import FirstHandClient
client = FirstHandClient(api_key=os.environ["FIRSTHAND_API_KEY"])Error Responses
If authentication fails, the API returns:
{
"error": {
"type": "authentication_error",
"message": "Invalid or missing API key",
"request_id": "req_01HV..."
}
}| Status | Cause |
|---|---|
401 | Missing or invalid API key |
403 | Key doesn’t have required scope for this endpoint |