Quickstart
Post your first content collection job in 5 minutes.
0. Create an Account
POST /v1/auth/signupcurl -X POST https://api.firsthandapi.com/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{
"name": "Your Org Name",
"email": "you@example.com"
}'Response: 200 OK
{
"organization_id": "org_01JQ...",
"api_key": "fh_live_...",
"credits_cents": 1000
}You’ll receive $10 in free credits to get started. Save your api_key — it is only shown once.
1. Get your API key
Sign up at firsthandapi.com and create an API key from the dashboard.
Your key will look like fh_live_... (production) or fh_test_... (sandbox).
2. Install an SDK
npm install @firsthand/sdkpip install firsthand3. Post a job
import { FirstHandClient } from '@firsthand/sdk';
const client = new FirstHandClient({ apiKey: 'fh_live_...' });
const job = await client.createJob({
type: 'data_collection',
description: 'Take a clear photo of any coffee cup from above. Must show the full cup.',
files_needed: 50,
accepted_formats: ['image/jpeg', 'image/png'],
price_per_file_cents: 75,
});
console.log(job.id); // job_01JQ...
console.log(job.status); // openfrom firsthand import FirstHandClient
client = FirstHandClient(api_key="fh_live_...")
job = client.create_job({
"type": "data_collection",
"description": "Take a clear photo of any coffee cup from above. Must show the full cup.",
"files_needed": 50,
"accepted_formats": ["image/jpeg", "image/png"],
"price_per_file_cents": 75,
})
print(job["id"]) # job_01JQ...
print(job["status"]) # open4. Get submissions
Option A: Webhook (recommended)
Register a webhook endpoint to receive submission.approved events:
curl -X POST https://api.firsthandapi.com/v1/webhook_endpoints \
-H "Authorization: Bearer fh_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/firsthand",
"events": ["submission.approved", "job.completed"]
}'Option B: Poll for files
const files = await client.getJobFiles('job_01JQ...');
// files.data = [{ id: "file_01JQ...", url: "https://...", ai_star_rating: 4, ... }]files = client.get_job_files("job_01JQ...")
# files["data"] = [{"id": "file_01JQ...", "url": "https://...", "ai_star_rating": 4, ...}]5. AI Quality Scores
Every submission is automatically scored by a multi-model AI ensemble:
| Score | Meaning |
|---|---|
| 5 stars | Exceptional quality, exactly what was requested |
| 4 stars | Good quality, meets requirements |
| 3 stars | Acceptable quality, auto-approved |
| 2 stars | Below threshold, auto-rejected |
| 1 star | Poor quality or irrelevant, auto-rejected |
Files scoring 3+ stars are auto-approved and delivered to your job folder.
Next steps
- Writing Job Descriptions — Get better files with clear descriptions
- AI Agent Integration — MCP server setup for Claude Code
- Credit Billing — Fund your account and manage billing
- Webhook Handling — Signature verification and best practices