API ReferenceSubmissions

Submissions

Submissions represent files uploaded by workers for a job. Each submission is automatically scored by AI.

Submission Lifecycle

  ┌───────────────┐     AI scores     ┌──────────┐
  │ pending_score  │ ──── 3-5★ ──────▶│ approved │
  └───────────────┘                    └──────────┘

         │  AI scores 1-2★

  ┌──────────┐      worker retries    ┌───────────────┐
  │ rejected │ ◀───────────────────── │ retry_pending  │
  └──────────┘                        └───────────────┘
StatusDescription
pending_scoreUploaded by worker, waiting for AI scoring (typically 5-15 seconds)
approvedScored 3+ stars — file delivered to buyer’s job folder, worker earns payout
rejectedScored 1-2 stars — worker receives AI feedback and can retry
retry_pendingWorker has re-accepted the job to submit a new attempt

Scoring threshold: Submissions scoring 3+ stars are auto-approved. Submissions scoring 1-2 stars are auto-rejected with AI-generated feedback explaining why.

Pre-scoring rejections: Submissions that fail resolution checks (min_width/min_height) are auto-rejected with 1 star before AI scoring runs. These rejections do not consume credits.

Job slot recovery: When a submission is rejected, the job’s slot reopens. If the job was in filled status (all slots taken by pending submissions), it reverts to open so other workers can accept it. This prevents jobs from getting stuck when submissions are rejected.

Timing: AI scoring typically completes within 5-15 seconds of upload. Use the submission.scored webhook event to get notified immediately.

List Submissions

GET /v1/submissions

List submissions across all jobs for your organization.

Query Parameters:

ParamTypeDescription
job_idstringFilter by job ID
statusstringFilter: pending_score, approved, rejected, retry_pending
min_scoreintegerMinimum AI star rating (1-5)
start_datestringStart date (ISO 8601, default: 30 days ago)
end_datestringEnd date (ISO 8601, default: now)
limitintegerMax results (1-100, default 20)
cursorstringPagination cursor

Response:

{
  "object": "list",
  "data": [
    {
      "object": "submission",
      "id": "sub_01JQ...",
      "job_id": "job_01JQ...",
      "worker_id": "wkr_01JQ...",
      "status": "approved",
      "ai_star_rating": 4,
      "ai_reasoning": "Clear, well-lit photo that matches the job description. Subject is centered and in focus.",
      "file_url": "https://files.firsthandapi.com/...",
      "content_type": "image/jpeg",
      "size_bytes": 2450000,
      "submitted_at": "2026-03-16T14:30:00Z",
      "scored_at": "2026-03-16T14:30:05Z"
    }
  ],
  "has_more": true,
  "next_cursor": "..."
}

Get Submission

GET /v1/submissions/{submission_id}

Retrieve a single submission by ID, including its AI star rating and reasoning.

Response:

{
  "object": "submission",
  "id": "sub_01JQ...",
  "job_id": "job_01JQ...",
  "worker_id": "wkr_01JQ...",
  "status": "approved",
  "ai_star_rating": 4,
  "ai_reasoning": "Clear, well-lit photo that matches the job description. Subject is centered and in focus with good composition.",
  "file_url": "https://files.firsthandapi.com/...",
  "content_type": "image/jpeg",
  "size_bytes": 2450000,
  "submitted_at": "2026-03-16T14:30:00Z",
  "scored_at": "2026-03-16T14:30:05Z"
}

Submission Summary

GET /v1/submissions/summary

Returns aggregate submission metrics for your organization.

Query Parameters:

ParamTypeDescription
job_idstringFilter by job ID
start_datestringStart date (ISO 8601, default: 30 days ago)
end_datestringEnd date (ISO 8601, default: now)

Response:

{
  "object": "submission_summary",
  "total_submissions": 1250,
  "approved": 1050,
  "rejected": 200,
  "approval_rate": 0.84,
  "avg_ai_star_rating": 3.8,
  "by_type": [
    {
      "type": "data_collection",
      "total": 800,
      "approved": 700,
      "avg_ai_star_rating": 4.0
    }
  ]
}