---
title: "Submit a sourcing brief and run it server-side"
method: POST
path: "/v1/briefs"
---

# Submit a sourcing brief and run it server-side

`POST /v1/briefs`

## Request

- Base URL: `https://api.githunt.ai`
- URL: `https://api.githunt.ai/v1/briefs`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-Api-Key`

Runs a whole sourcing brief on the server instead of making the caller orchestrate dozens of searches and evidence polls. The run expands the requested regions into countries, searches them three at a time against the candidate pool, ranks the union, gathers evidence reports for a bounded shortlist, and splits the shortlist into delivered profiles and screening leads. Countries your exclusions would discard anyway are skipped before any search runs, and listed in `coverage.countries_skipped`.

Returns `202` with a `brief_id` immediately; poll `GET /v1/briefs/{brief_id}` for the result. Debits 25 credits once, at submission: about fifteen pool searches plus up to twenty-five evidence builds reused from the shared cache, priced below the sum of the equivalent `search` and `evidence` calls. Polling is free of monthly credits. A `400` is uncharged.

A brief may name up to six `regions`, more than one search request may carry, because it expands and batches its own geography. Every criteria and exclusion field is validated by the same rules `POST /v1/search` applies, and every ceiling in the run is server-controlled.

Public evidence can never establish commercial tenure, employment, or any closed-source work. A delivered profile means a stated location that resolved to a single country offset plus at least one inspected, candidate-authored in-window commit in a requested skill; everything else is a screening lead with a stated reason.

## Request body

- BriefRequest
  - `criteria` object, required: What the candidate must be. At least one language or skill is needed for evidence to be gathered.
    - `languages` string[]
    - `skills` string[]
    - `role` string: Role profile to score against, same list as `POST /v1/search`.
    - `sectors` string[]: Employer sectors to favour via the employer graph, max 5.
    - `domains` string[]: Domain packs to assess core subject-matter work against, max 3. Without a domain every card comes back with domain tier `none`.
    - `skillRecency` object[]: Hard eligibility filter on evidenced skill recency, same shape as search.
      - `skill` string
      - `minActiveYears` number
      - `usedWithinYears` number
  - `geography` object, required: Where to look, and where not to. At least one of `regions` or `locations` is required.
    - `regions` string[]: Regions to cover, max 6 - more than a single search request may carry. Each expands into countries searched three at a time, so every country gets the ranker's full scoring depth.
    - `locations` string[]
    - `excludeLocations` string[]
    - `excludeUtcOffsets` object: Inclusive UTC offset band to exclude at the run timestamp, with DST applied. `{min: 0, max: 5}` leaves +5:30 and +5:45 eligible.
      - `min` number
      - `max` number
    - `includeUnlocated` boolean: Include candidates with no stated location. They can never be delivered, only surfaced as screening leads.
  - `deliver` object
    - `maxProfiles` integer
    - `maxScreeningLeads` integer
    - `evidence` boolean: Gather evidence reports for the shortlist. With `false` the run is faster but no profile carries verified commits, so every result is a lead.

## Response `202`

Brief accepted and queued (debits 25 credits)

- BriefAcceptedResponse
  - `success` true
  - `data` object
    - `brief_id` string, uuid
    - `status` 'queued'
    - `retry_after_seconds` integer: Matches the `Retry-After` header. Do not poll faster.
  - `meta` Meta: Envelope metadata. `quota.cost` is 0 on endpoints that debit no credits.
    - `requestId` string
    - `quota` Quota
      - `used` integer
      - `limit` integer: -1 means unlimited
      - `month` string
      - `cost` integer: Credits this request debited (search: 1, get user: 1, evidence report: 3 when a report is returned and 0 while pending, analyze profile: 3, list operations: 0). `used` already reflects this charge.
      - `rollover` integer: Unused credits banked from the previous month and available on top of `limit` this month (`remaining` = limit + rollover - used). Only present on the Team plan, capped at one extra month's allowance (so at most 2x the allowance is usable in a month).

## Other responses

- `400`: Invalid request
- `401`: Missing, invalid, or revoked API key
- `429`: Monthly or daily quota exceeded
- `500`: Unexpected server error

---

[API](https://skmtc.dev/githunt/apis/githunt-api.md) · [All operations](https://skmtc.dev/githunt/apis/githunt-api/llms.txt) · [OpenAPI document](https://skmtc.dev/githunt/apis/githunt-api/revisions/6fc325607da0?raw)
