githunt-ai Briefs API

The Briefs API from githunt-ai — 2 operation(s) for briefs.

Operations 2

POST /v1/briefs Submit a sourcing brief and run it server-side #
GET /v1/briefs/{briefId} Poll a sourcing brief #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/githunt-ai:githunt-ai-briefs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

githunt-ai-briefs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: GitHunt Briefs API
  version: 1.0.0
  description: 'Search, look up, and analyze GitHub developers programmatically. GitHunt gives you millisecond access to millions of developers available on GitHub - ranked, scored, and with contact details where publicly available. Every request is billed against your plan''s monthly API call quota; all plans are additionally capped at 2000 calls/day.

    Quotas: Free 50 calls/month (trial), Pro 1000 calls/month, Team 1500 calls/month (unused credits roll over, up to one extra month''s allowance), Enterprise unlimited. Endpoints cost different amounts of quota: search 1 credit, get user 1 credit, evidence report 3 credits (0 when the report is still pending), analyze profile 3 credits, and every /v1/lists operation 0 credits. Endpoints that debit 0 credits still count against the daily cap.'
  contact:
    email: support@githunt.ai
servers:
- url: https://api.githunt.ai
security:
- bearerAuth: []
- apiKeyAuth: []
tags:
- name: Briefs
paths:
  /v1/briefs:
    post:
      operationId: createBrief
      summary: Submit a sourcing brief and run it server-side
      description: '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.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BriefRequest'
      responses:
        '202':
          description: Brief accepted and queued (debits 25 credits)
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before the first poll
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BriefAcceptedResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/QuotaExceeded'
        '500':
          $ref: '#/components/responses/InternalError'
      tags:
      - Briefs
  /v1/briefs/{briefId}:
    get:
      operationId: getBrief
      summary: Poll a sourcing brief
      description: 'Returns the brief''s status and progress while it runs, and the full result once it is `complete` or `partial`. `partial` means the whole brief did not run: a ceiling was hit (search calls or time budget), a batch held more ranked rows than the run could read (`coverage.truncated`), or evidence was still building. Report the regions actually covered rather than claiming exhaustive coverage. Debits 0 monthly credits; every call still passes the daily cap. Only the account that submitted the brief can read it; anyone else gets the same `404` as a brief that does not exist.'
      parameters:
      - name: briefId
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The `brief_id` returned by `POST /v1/briefs`
      responses:
        '200':
          description: Brief status. Carries `result` when `status` is `complete` or `partial`, and `retry_after_seconds` while it is still running.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Present while the brief is still running
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BriefStatusResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/QuotaExceeded'
        '500':
          $ref: '#/components/responses/InternalError'
      tags:
      - Briefs
components:
  responses:
    InternalError:
      description: Unexpected server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing, invalid, or revoked API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    QuotaExceeded:
      description: Monthly or daily quota exceeded
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds until the quota resets
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: No matching developer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    ErrorResponse:
      type: object
      required:
      - success
      - error
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
              enum:
              - unauthorized
              - quota_exceeded
              - invalid_request
              - not_found
              - internal
            message:
              type: string
    BriefAcceptedResponse:
      type: object
      properties:
        success:
          type: boolean
          const: true
        data:
          type: object
          properties:
            brief_id:
              type: string
              format: uuid
            status:
              type: string
              const: queued
            retry_after_seconds:
              type: integer
              description: Matches the `Retry-After` header. Do not poll faster.
        meta:
          $ref: '#/components/schemas/Meta'
    BriefCard:
      type: object
      description: One evidence-backed profile. Identity, verified skill evidence, public commercial signals, domain evidence, and a screening question for every unknown. Every status and reason comes from the same criterion rules `GET /v1/users/{login}/evidence` applies.
      properties:
        login:
          type: string
        name:
          type: string
          nullable: true
        location:
          type: string
          nullable: true
        location_resolution:
          type: object
          nullable: true
          description: How the stated base resolved at the run timestamp. Only `resolved` can be delivered; `ambiguous` and `unresolved` are screening leads.
          properties:
            status:
              type: string
              enum:
              - resolved
              - ambiguous
              - unresolved
            country:
              type: string
              nullable: true
            utc_offset:
              type: object
              nullable: true
            basis:
              type: string
              nullable: true
            screening_reason:
              type: string
              nullable: true
            observed_at:
              type: string
        company:
          type: string
          nullable: true
        bio:
          type: string
          nullable: true
        hireable:
          nullable: true
        profile_url:
          type: string
        score:
          type: number
          nullable: true
        rank_breakdown:
          type: object
          nullable: true
          description: Why the ranker placed this row where it did. Present when the brief named languages, skills, sectors, organizations or domains.
          properties:
            base:
              type: number
              description: Score before the evidence multipliers.
            recency:
              type: number
            org:
              type: number
            domain:
              type: number
            final:
              type: number
              description: The value the ordering actually used.
        discovered_by:
          type: array
          items:
            type: string
          description: Which location batches surfaced this candidate.
        evidence_status:
          type: string
          enum:
          - cached
          - built
          - pending
          - skipped
        evaluated_at:
          type: string
          nullable: true
        window:
          type: object
          nullable: true
        coverage:
          type: object
          nullable: true
          description: The evidence scan's own coverage, as on the evidence endpoint.
        criteria:
          type: object
          nullable: true
          description: The evidence report's criterion assessments, verbatim.
        skill_evidence:
          type: object
          properties:
            status:
              type: string
            reason:
              type: string
              nullable: true
            inspected_in_window:
              type: integer
              description: Inspected candidate-authored in-window commits in a requested skill. One or more is what makes a card deliverable.
            last_commit:
              type: string
              nullable: true
            repos:
              type: array
              items:
                type: object
                properties:
                  repository:
                    type: string
                  url:
                    type: string
                  owner_type:
                    type: string
                    nullable: true
                  commits_seen:
                    type: integer
                  commits_in_window:
                    type: integer
                  inspected:
                    type: integer
                  last_commit:
                    type: string
                    nullable: true
            commits:
              type: array
              items:
                type: object
                properties:
                  url:
                    type: string
                    nullable: true
                  date:
                    type: string
                    nullable: true
                  message:
                    type: string
                    nullable: true
                  repository:
                    type: string
                    nullable: true
                  files_changed:
                    type: integer
                    nullable: true
                  code_languages:
                    type: array
                    items:
                      type: string
        commercial_signals:
          type: object
          description: Public context for paid work, never a tenure claim. `tenure_status` is `unknown` unless a dated, corroborated interval exists.
          properties:
            public_signals_only:
              type: boolean
              const: true
            tenure_status:
              type: string
            tenure_reason:
              type: string
              nullable: true
            items:
              type: array
              items:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                    - public_org_contribution
                    - self_reported_employment
                    - commit_email_domain
                  value:
                    type: string
                  url:
                    type: string
                    nullable: true
                  organization:
                    type: string
                    nullable: true
                  company:
                    type: string
                    nullable: true
                  interval:
                    type: object
                    nullable: true
                  commits:
                    type: integer
                    nullable: true
                  active_years:
                    type: array
                    items:
                      type: integer
                  languages:
                    type: array
                    items:
                      type: string
        domain_evidence:
          type: object
          properties:
            tier:
              type: string
              enum:
              - core
              - adjacent
              - generic
              - none
              description: '`core` only when the evidence report''s `core_domain_recent` criterion is supported. A core term in a README or a commit subject is context and lands as `adjacent` at best.'
            status:
              type: string
            reason:
              type: string
              nullable: true
            subsystems:
              type: array
              items:
                type: string
            items:
              type: array
              items:
                type: object
                properties:
                  url:
                    type: string
                    nullable: true
                  date:
                    type: string
                    nullable: true
                  term:
                    type: string
                  pack:
                    type: string
                  subsystem:
                    type: string
                    nullable: true
                  context:
                    type: string
                    nullable: true
                  kind:
                    type: string
                  repository:
                    type: string
                    nullable: true
        screening_questions:
          type: array
          items:
            type: string
        links:
          type: object
          properties:
            profile:
              type: string
            blog:
              type: string
            twitter:
              type: string
    BriefRequest:
      type: object
      required:
      - criteria
      - geography
      properties:
        criteria:
          type: object
          description: What the candidate must be. At least one language or skill is needed for evidence to be gathered.
          properties:
            languages:
              type: array
              items:
                type: string
              example:
              - Scala
            skills:
              type: array
              items:
                type: string
            role:
              type: string
              description: Role profile to score against, same list as `POST /v1/search`.
            sectors:
              type: array
              items:
                type: string
              description: Employer sectors to favour via the employer graph, max 5.
            domains:
              type: array
              items:
                type: string
              example:
              - payments
              description: Domain packs to assess core subject-matter work against, max 3. Without a domain every card comes back with domain tier `none`.
            skillRecency:
              type: array
              description: Hard eligibility filter on evidenced skill recency, same shape as search.
              items:
                type: object
                properties:
                  skill:
                    type: string
                  minActiveYears:
                    type: number
                  usedWithinYears:
                    type: number
        geography:
          type: object
          description: Where to look, and where not to. At least one of `regions` or `locations` is required.
          properties:
            regions:
              type: array
              maxItems: 6
              items:
                type: string
              example:
              - north-america
              - latin-america
              description: 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:
              type: array
              maxItems: 20
              items:
                type: string
            excludeLocations:
              type: array
              items:
                type: string
              example:
              - India
            excludeUtcOffsets:
              type: object
              description: 'Inclusive UTC offset band to exclude at the run timestamp, with DST applied. `{min: 0, max: 5}` leaves +5:30 and +5:45 eligible.'
              properties:
                min:
                  type: number
                max:
                  type: number
            includeUnlocated:
              type: boolean
              description: Include candidates with no stated location. They can never be delivered, only surfaced as screening leads.
        deliver:
          type: object
          properties:
            maxProfiles:
              type: integer
              minimum: 1
              maximum: 25
              default: 10
            maxScreeningLeads:
              type: integer
              minimum: 0
              maximum: 50
              default: 15
            evidence:
              type: boolean
              default: true
              description: Gather evidence reports for the shortlist. With `false` the run is faster but no profile carries verified commits, so every result is a lead.
    Quota:
      type: object
      properties:
        used:
          type: integer
        limit:
          type: integer
          description: -1 means unlimited
        month:
          type: string
          example: 2026-07
        cost:
          type: integer
          description: '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.'
          example: 1
        rollover:
          type: integer
          description: 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).
          example: 340
    Meta:
      type: object
      description: Envelope metadata. `quota.cost` is 0 on endpoints that debit no credits.
      properties:
        requestId:
          type: string
        quota:
          $ref: '#/components/schemas/Quota'
    BriefStatusResponse:
      type: object
      properties:
        success:
          type: boolean
          const: true
        data:
          type: object
          properties:
            brief_id:
              type: string
              format: uuid
            status:
              type: string
              enum:
              - queued
              - running
              - complete
              - partial
              - failed
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
            progress:
              type: object
              description: Live counters while the run is in flight.
              properties:
                phase:
                  type: string
                  enum:
                  - queued
                  - search
                  - evidence
                  - done
                  - failed
                searches_done:
                  type: integer
                searches_planned:
                  type: integer
                candidates:
                  type: integer
                shortlisted:
                  type: integer
                evidence_ready:
                  type: integer
                evidence_pending:
                  type: integer
            retry_after_seconds:
              type: integer
              description: Present while the brief is still running.
            error:
              type: string
              description: Present when `status` is `failed`.
            result:
              $ref: '#/components/schemas/BriefResult'
        meta:
          $ref: '#/components/schemas/Meta'
    BriefResult:
      type: object
      description: Present once the brief is `complete` or `partial`.
      properties:
        cover:
          type: object
          description: The brief as run, plus the assumptions every claim below rests on.
          properties:
            brief_id:
              type: string
            prepared_at:
              type: string
              format: date-time
            criteria:
              type: object
            geography:
              type: object
            assumptions:
              type: array
              items:
                type: string
            delivered:
              type: integer
            screening_leads:
              type: integer
            requested_profiles:
              type: integer
        summary:
          type: array
          description: One row per delivered profile, in delivery order.
          items:
            type: object
            properties:
              rank:
                type: integer
              login:
                type: string
              name:
                type: string
                nullable: true
              location:
                type: string
                nullable: true
              utc_offset:
                type: object
                nullable: true
              last_skill_commit:
                type: string
                nullable: true
              inspected_in_window:
                type: integer
              domain_tier:
                type: string
                enum:
                - core
                - adjacent
                - generic
                - none
              tenure_status:
                type: string
              screening_questions:
                type: integer
              recency:
                type: number
                nullable: true
                description: The recency multiplier from `rank_breakdown`.
              org:
                type: number
                nullable: true
              domain:
                type: number
                nullable: true
        profiles:
          type: array
          items:
            $ref: '#/components/schemas/BriefCard'
        screening_leads:
          type: array
          description: Cards that did not meet a delivery rule, each with a `reason`. Overflow beyond `maxProfiles` appears here too.
          items:
            allOf:
            - $ref: '#/components/schemas/BriefCard'
            - type: object
              properties:
                reason:
                  type: string
        coverage:
          type: object
          description: What was actually searched. Never a claim of worldwide coverage.
          properties:
            regions_requested:
              type: array
              items:
                type: string
            countries_searched:
              type: array
              items:
                type: string
            countries_skipped:
              type: array
              description: Countries the region expansion produced that the brief would have discarded anyway, so no search was spent on them.
              items:
                type: object
                properties:
                  country:
                    type: string
                  reason:
                    type: string
                    enum:
                    - excluded_location
                    - utc_offset_band
                    description: '`excluded_location` - named in `excludeLocations`. `utc_offset_band` - the country''s whole UTC range sits inside `excludeUtcOffsets` at the run timestamp. A country only partly inside the band is still searched.'
            batches_planned:
              type: integer
            batches_run:
              type: integer
            search_calls:
              type: integer
            candidate_rows:
              type: integer
              description: Rows returned before dedup, the denominator for a duplicate rate.
            unique_candidates:
              type: integer
            shortlisted:
              type: integer
            evidence:
              type: object
              properties:
                cached:
                  type: integer
                built:
                  type: integer
                pending:
                  type: integer
                skipped:
                  type: integer
            truncated:
              type: boolean
              description: A batch's ranking held more rows than the run could read, so some ranked candidates were never seen.
            retrieval_capped:
              type: boolean
              description: 'True when the ranker''s per-location retrieval ceiling was reached for at least one country: more candidates may exist there than this run could read. A capped read is not an incomplete run - absence under a cap is not evidence of absence - and it does not by itself make `status` `partial`.'
            partial:
              type: boolean
              description: True when a ceiling was hit, a batch was truncated, or evidence was still building. `status` is `partial` exactly when this is. A per-location retrieval cap is reported separately as `retrieval_capped`.
            stopped_reason:
              type: string
              nullable: true
              enum:
              - search_call_ceiling
              - time_budget
              - null
            batches:
              type: array
              items:
                type: object
            note:
              type: string
        manifest:
          type: object
          description: Everything needed to reproduce or compare two runs.
          properties:
            brief_id:
              type: string
            run_started_at:
              type: string
              format: date-time
            run_completed_at:
              type: string
              format: date-time
            skills:
              type: array
              items:
                type: string
            domains:
              type: array
              items:
                type: string
            evidence_requested:
              type: boolean
            evidence_cache_key:
              type: string
              nullable: true
            evidence_schema_version:
              type: integer
            inspection_rules_version:
              type: integer
            ceilings:
              type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Authorization: Bearer ghk_live_...'
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key