---
title: "Approved creators on sale now, by name, with price per format and format advice"
method: GET
path: "/creators"
---

# Approved creators on sale now, by name, with price per format and format advice

`GET /creators`

## Request

- Base URL: `https://app.distribution.tech/api/v1`
- URL: `https://app.distribution.tech/api/v1/creators`
- Auth: HTTP bearer

Scope: creators:read.

## Query parameters

- `q` string
- `segment` string
- `reach_band` 'nano' | 'micro' | 'mid' | 'macro' | 'mega'
- `goal` 'launch' | 'funding' | 'feature' | 'program'
- `match` string
- `limit` integer
- `offset` integer
- `fit` boolean
- `country` string
- `language` string
- `followers_min` integer
- `followers_max` integer
- `er_min` number
- `match_min` integer
- `format` 'post' | 'quote' | 'thread'
- `price_min` integer
- `price_max` integer
- `sort` 'match' | 'followers' | 'engagement' | 'views' | 'price'
- `dir` 'desc' | 'asc'
- `budget` integer

## Response `200`

OK

- Creators
  - `total` integer: How many creators this answer lists: the shortlist, never a count of the network.
  - `priced` integer: How many of total are bookable now by the one rule in the API description (What bookable means); the rest carry price_estimate, never a price.
  - `catalog` object: The whole network, whatever this call filtered: the same counts as the app and the site (GET /api/network/facts on the app host), refreshed at most every five minutes. Left out when the network cannot be counted right now, never guessed.
    - `approved` integer, required: Every approved, verified, active creator in the network, priced or not.
    - `priced` integer, required: Of those, the creators bookable now by the one rule in the API description (What bookable means): the number the app and the site show.
  - `cap` integer: How many creators the selection holds (the same as total).
  - `limit` integer: This page's size: default 24, at most 50.
  - `offset` integer: Where this page starts, at most total (an offset past the end is answered as total); the next page starts at offset + limit while it is below total.
  - `creators` CreatorSummary[]: Summary rows, best fits first by score and in the order asked for: no handle, link or posts. GET /creators/{id} (creator_get) opens one in full.
    - `id` string, uuid
    - `name` string, nullable
    - `status` 'approved' | 'borderline' | 'not_reviewed' | 'declined'
    - `status_label` string
    - `status_reason` string
    - `in_automatic_plans` boolean
    - `match_score` integer, nullable
    - `match_label` string, nullable
    - `on_sale` boolean
    - `reach_band` 'nano' | 'micro' | 'mid' | 'macro' | 'mega': The creator's size by followers, smallest to largest.
    - `median_views_30d` integer, nullable: Deprecated: the same number as median_views_30d_network. Removed on 2027-01-11; read median_views_30d_network.
    - `median_views_30d_network` integer, nullable: Median views per post over the creator's last 30 days, as the network measures it across all their posts. Prices, expected views and format advice use this number. It can differ from posts_summary.posts_sample_median_views, which covers only the posts we hold.
    - `followers` integer, nullable: X followers, as the network last measured them. Null when not measured.
    - `verified_badge` boolean, nullable: Whether the account carries the X blue check. Null when unknown.
    - `country` string, nullable: The country or region X shows on the account's About panel. Null when X shows none; never inferred.
    - `language` string, nullable: The language the creator posts in, as a name (for example English). Null when unknown.
    - `segments` string[]
    - `bio` string, nullable
    - `positioning` string, nullable: One line on who the creator is, taken from their own bio (never written by us); null when the bio has none.
    - `avatar_url` string, nullable
    - `ask_price` boolean: true when nothing is on sale for this creator: the action is Ask for a price (creator_ask_price, POST /creators/{id}/price-request), which asks our team, never the creator; price_estimate is an estimate, never a price. false when a format is on sale: add it from offerings with plan_add_creator.
    - `price_estimate` object, nullable: For a creator with nothing on sale: an estimated price range from its metrics (the ERP's suggested budget band), never a price; null when it has a price. Ask for a price (creator_ask_price, POST /creators/{id}/price-request) asks our team for a real one; the creator is never contacted directly.
      - `min_usd` integer, required
      - `max_usd` integer, required
      - `label` string, required: As the app shows it, e.g. "Est. $1,200 to $2,500" ("to", never a dash).
      - `provenance` object: DT-159: where this number came from: source, method, measured_at, expires_at, label (Verified, Creator-reported or Estimated), stale, and as_of text.
        - `source` string
        - `method` string
        - `measured_at` string, nullable
        - `expires_at` string, nullable
        - `label` 'Verified' | 'Creator-reported' | 'Estimated'
        - `stale` boolean
        - `as_of` string, nullable
      - `calc` object, required: How this number was made (DT-117): the calculation version and its inputs, the same on every surface. Never a cost or a fee.
        - `calc_version` string, required
        - `inputs` object, required
    - `engagement_rate_30d` number, nullable
    - `posts_per_week` number, nullable
    - `match_reasons` object[]: Why this creator (row 7858), each from a number the network holds: topic (the brand's segments the creator posts about; a topic match, not audience overlap), reach (median views a post over 30 days, with its as-of date), past_launches (launches posted about), engagement (only when above the median of the creators listed). Empty when none can be said; never a price.
      - `kind` 'topic' | 'reach' | 'past_launches' | 'engagement', required
      - `text` string, required
    - `past_collabs` ListedCollab[]: Launches the creator posted or quoted among the launches the network tracks, newest first (at most 12), then detected paid partnerships. An empty list means none was found in the launches we track, not that the creator never worked with a brand.
      - `project` string, required: The project or brand.
      - `title` string, nullable: The launch's own title, when it says more than the project name.
      - `date` string, date, nullable: When the launch went out.
      - `role` 'Launch post' | 'Quoted the launch' | 'Paid partnership', required: What the creator did.
      - `brand` object: Who the launch was for, without a handle (a list names no X account): avatar_url, else the site's favicon, else initials.
        - `avatar_url` string, nullable
        - `site` string, nullable
        - `initials` string
    - `offerings` Offering[]
      - `unit_id` string, uuid
      - `format` 'post' | 'quote' | 'thread'
      - `label` string
      - `deliverable` string, nullable: One line on what the creator delivers for this format.
      - `price_cents` integer: The one all-in price you pay, when buyable is true. When buyable is false this is the last price on file and is not bookable: a creator's price counts for 30 days, so an older one needs re-confirming (Ask for a price, creator_ask_price or POST /creators/{id}/price-request, asks our team for a current price).
      - `buyable` boolean: True when this format can be booked now at price_cents: the creator is approved and the price is current (at most 30 days old, or a price our team set). False means price on request until the price is re-confirmed.
      - `price_as_of` string, date
      - `expected_views` integer, nullable
      - `cost_per_1k_views_cents` integer, nullable
      - `provenance` object: DT-159: where this number came from: source, method, measured_at, expires_at, label (Verified, Creator-reported or Estimated), stale, and as_of text.
        - `source` string
        - `method` string
        - `measured_at` string, nullable
        - `expires_at` string, nullable
        - `label` 'Verified' | 'Creator-reported' | 'Estimated'
        - `stale` boolean
        - `as_of` string, nullable
      - `calc` object: How this number was made (DT-117): the calculation version and its inputs, the same on every surface. Never a cost or a fee.
        - `calc_version` string, required
        - `inputs` object, required
    - `synced_at` string, date-time, nullable: When the creator's profile and posts were last synced (ISO 8601). Null when unknown.
    - `refresh_failed_at` string, date-time, nullable: When the last nightly refresh of this creator failed (ISO 8601); null when the last refresh worked or none has run. The figures then stay as of synced_at.
    - `advice` object
      - `recommended` 'post' | 'quote' | 'null', nullable
      - `reason` string
    - `views_series` integer[]: The shape of their recent posts' views, oldest first, at most 30 points, each 0 to 100 against the highest (a sparkline, not view counts: those are median_views_30d). A post without a views count is left out; empty when none has one.

## Other responses

- `400`: A parameter is not valid: details.problems names each field and what it accepts.
- `401`: No API key, an unknown one, or a revoked one.
- `403`: The key does not have this endpoint's scope.
- `429`: Too many requests for this key in the current minute (60); Retry-After and RateLimit-Reset say when to try again. On POST /campaigns and on POST /plans/current/lines when it starts a plan: the brand's 3 new campaigns in 24 hours are used (details.reason daily_campaign_limit); details.resets_at and Retry-After say when the limit reopens, a rolling 24 hours from the first of them, not a calendar day; archiving or deleting a campaign does not give its slot back. On GET /creators and GET /creators/{id}: a creator read limit is used (details.reason per_minute, daily_lists, daily_reveals, daily_seen or locked). daily_seen is your workspace's one pool of 300 creator views a day (300 different creators shown or opened since midnight UTC), shared by the app and every API key of the brand: details.scope workspace and details.limit 300; a creator already seen today, in the app or through any key, still opens and costs nothing. The other reasons are this key's own limit (details.scope key) or the brand's ceiling over all its keys (details.scope api).
- `500`: internal: the request failed on our side. Try again.
- `503`: unavailable: the service or this part of it is not reachable right now. Try again shortly.

---

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