Quickstart

Quickstart

Post your first content collection job in 5 minutes.

0. Create an Account

POST /v1/auth/signup
curl -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/sdk
pip install firsthand

3. 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); // open
from 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"]) # open

4. Get submissions

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:

ScoreMeaning
5 starsExceptional quality, exactly what was requested
4 starsGood quality, meets requirements
3 starsAcceptable quality, auto-approved
2 starsBelow threshold, auto-rejected
1 starPoor quality or irrelevant, auto-rejected

Files scoring 3+ stars are auto-approved and delivered to your job folder.

Next steps