---
title: "Create Bounty Submission"
method: POST
path: "/bounty_submissions"
tags: ["Bounty Submissions"]
---

# Create Bounty Submission

`POST /bounty_submissions`

Creates a submission on a workforce bounty. Include a `deliverable` payload — any combination of links and uploaded files, with at least one of the two — and the submission goes straight to review; create is the only step. For `data_capture` bounties, omit the deliverable: this starts a claimed attempt whose proof accumulates server-side, and the separate submit endpoint sends it to review once complete. Requires a user credential — account API keys cannot author submissions.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `affiliate_code` string, nullable — Affiliate code crediting the referrer, when the worker arrived through one.
  - `bounty_id` string, required — The bounty to submit to (`bnty_` tag).
  - `deliverable` object, nullable — The submitted work. Combine `urls`, `file_ids`, and `caption` freely; at least one link or file is required.
    - `caption` string, nullable — Written context shown to reviewers alongside the work.
    - `file_ids` string[] — IDs of uploaded files attached as work, up to 10, each prefixed `file_`. Combinable with `urls` and `caption`.
    - `type` 'content_url' | 'media' | 'null', nullable — Legacy shape selector; no longer selects anything. When present it must name an inline shape (`content_url` or `media`).
    - `urls` string[] — Links to the posted work, up to 10. Combinable with `file_ids` and `caption`.
  - `metadata` object, nullable — Optional capture metadata describing where and how the footage was recorded. Persisted on the submission. On a `data_capture` bounty every field except `fov` is required whenever metadata is provided.
    - `city` string, nullable — City the footage was recorded in.
    - `country` string, nullable — Country the footage was recorded in.
    - `device` string, nullable — Device the footage was recorded on.
    - `fov` integer, nullable — Horizontal field of view in degrees.
    - `operator` string, nullable — Identifier of the person who recorded the footage.
    - `site` string, nullable — Site or venue the footage was recorded at.
    - `station` string, nullable — Station or position within the site.

## Response `201`

submission created with an inline deliverable

- BountySubmission
  - `bounty_id` string, required — The bounty the work was submitted to, prefixed `bnty_`.
  - `capture_clips` BountyCaptureClip[], nullable, required
    - `bounty_submission_id` string, required — The bounty submission (attempt) this clip belongs to, prefixed `btys_`.
    - `created_at` string, required — When the clip was created, as an ISO 8601 timestamp.
    - `duration_seconds` integer, nullable, required — Server-validated clip duration in whole seconds. `null` until validation completes.
    - `failure_code` string, nullable, required — Stable validation failure code. `null` unless `status` is `failed`.
    - `failure_message` string, nullable, required — Human-readable validation failure reason. `null` unless `status` is `failed`.
    - `frames_url` string, nullable, required — Temporary signed URL for the video frame timestamp log. Returned only on single-clip reads for an authorized viewer; `null` on list responses or until the artifact is attached.
    - `id` string, required — Capture clip ID, prefixed `bclip_`.
    - `imu_url` string, nullable, required — Temporary signed URL for the IMU (accelerometer + gyroscope) log. Returned only on single-clip reads for an authorized viewer; `null` on list responses or until the artifact is attached.
    - `manifest_url` string, nullable, required — Temporary signed URL for the capture manifest. Returned only on single-clip reads for an authorized viewer; `null` on list responses or until the artifact is attached.
    - `ready_at` string, nullable, required — When server-side validation completed successfully, as an ISO 8601 timestamp. `null` until then.
    - `sequence` integer, required — The clip's stable order within the attempt, starting at 1.
    - `status` 'recording' | 'verifying' | 'ready' | 'failed', required — Recording and validation state. `recording` is still capturing; `verifying` is running server-side validation; `ready` passed validation and counts toward the verified-duration payout gate; `failed` did not validate.
    - `updated_at` string, required — When the clip was last updated, as an ISO 8601 timestamp.
    - `video_url` string, nullable, required — Temporary signed URL for the synchronized MP4 video. Returned only on single-clip reads for an authorized viewer; `null` on list responses or until the artifact is attached.
  - `capture_filename` string, nullable, required — The vendor filename stem `Country_City_Site_Station_Operator`, derived from the capture metadata. `null` until every component is present.
  - `captured_clip_count` integer, required — Number of verified capture clips accepted for this submission so far. `0` for submissions whose deliverable doesn't accumulate clips.
  - `captured_duration_seconds` integer, required — Total verified duration of accepted capture clips, in whole seconds. `0` for submissions whose deliverable doesn't accumulate clips.
  - `city` string, nullable, required — Capture metadata: city the footage was recorded in. `null` unless capture metadata was provided.
  - `content` string, nullable, required — Written proof the worker submitted with their work.
  - `country` string, nullable, required — Capture metadata: country the footage was recorded in. `null` unless capture metadata was provided.
  - `created_at` string, required — When the submission was created, as an ISO 8601 timestamp.
  - `deliverable_type` 'content_url' | 'media' | 'data_capture' | 'null', nullable, required — How the work arrived when it came in through the API in one shot, informational only — read the work from `deliverable_urls`, `files`, and `capture_clips` directly. `null` for submissions whose proof is a livestream recording, including ones that attached links or files on submit.
  - `deliverable_urls` string[], nullable, required
  - `denial_reason` string, nullable, required — Why the submission was denied, when a presentable reason exists. Always `null` unless `status` is `denied`.
  - `device` string, nullable, required — Capture metadata: device the footage was recorded on. `null` unless capture metadata was provided.
  - `files` BountySubmissionFile[], required
    - `attachment_type` 'image' | 'video' | 'audio' | 'other' | 'null', nullable, required — Broad kind of file.
    - `content_type` string, nullable, required — MIME type of the file.
    - `filename` string, nullable, required — Name the file was uploaded with.
    - `id` string, required — File ID, prefixed `file_`.
    - `url` string, nullable, required — Temporary download URL for the file.
  - `fov` integer, nullable, required — Capture metadata: horizontal field of view in degrees. `null` when not reported.
  - `id` string, required — Submission ID, prefixed `btys_`.
  - `operator` string, nullable, required — Capture metadata: identifier of the person who recorded the footage. `null` unless capture metadata was provided.
  - `resolved_at` string, nullable, required — When the submission was approved or denied, as an ISO 8601 timestamp. `null` until then.
  - `site` string, nullable, required — Capture metadata: site or venue the footage was recorded at. `null` unless capture metadata was provided.
  - `station` string, nullable, required — Capture metadata: station or position within the site. `null` unless capture metadata was provided.
  - `status` 'in_progress' | 'submitted' | 'approved' | 'denied', required — Lifecycle state. `in_progress` submissions are active attempts that have not submitted proof yet; `submitted` submissions await review; `approved` submissions were accepted and paid; `denied` submissions were rejected.
  - `submitted_at` string, nullable, required — When proof was submitted for review, as an ISO 8601 timestamp. `null` while the attempt is in progress.
  - `updated_at` string, required — When the submission was last updated, as an ISO 8601 timestamp.
  - `worker` UserSummary, required
    - `id` string, required — User ID, prefixed `user_`.
    - `name` string, nullable, required — Display name.
    - `profile_picture` UserProfilePicture, required
      - `url` string, required — Avatar image URL. Always present — a generated placeholder when the user set no picture.
    - `username` string, required — Public username.

## Other responses

- `400` — Invalid Parameters
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Resource not found

---

[API](https://skmtc.net/whop/apis/whop-api.md) · [All operations](https://skmtc.net/whop/apis/whop-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/whop/whop-api/versions/db0883548bc5/schema)
