---
title: "Place an order"
method: POST
path: "/api/v1/orders"
tags: ["Orders"]
---

# Place an order

`POST /api/v1/orders`

## Request

- Base URL: `https://spoofy.social`
- URL: `https://spoofy.social/api/v1/orders`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `better-auth.session_token`

Charges your balance and starts delivery. Send an `Idempotency-Key` header so a retry never double-charges. With `dry_run: true` nothing is charged: you get the price, your balance and whether it is enough.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `service` integer, required
  - `link` string, required
  - `quantity` integer: How many. Left out where the inputs count it (comments, usernames) or it is fixed (packages, subscriptions); per run when spread over runs.
  - `inputs` OrderInputs: Order fields, for services with `input.fields`. Text we post for you is checked first (see text_blocked).
    - `comments` union: Custom comments: one per line (or a list), each different. Their number is the quantity.
      - string[]
      - string
    - `usernames` union: Mentions: the accounts to mention, one per line (or a list), at most 50. Their number is the quantity.
      - string[]
      - string
    - `hashtag` string: Mentions by hashtag: one hashtag, e.g. "#yourbrand".
    - `username` string: An account (handle or profile link): whose followers get mentioned, whose comment gets the likes, or a subscription’s account.
    - `answer_number` integer: Poll votes: the option to vote for, 1 = the first (GET /api/v1/polls reads the options).
    - `runs` integer: Spread the order over this many runs; `quantity` is then per run and you pay for quantity × runs. Only where `input.spread` is true.
    - `interval` integer: Minutes between runs.
    - `min` integer: Subscriptions: the least each new post gets.
    - `max` integer: Subscriptions: the most each new post gets.
    - `posts` integer: Subscriptions: how many of your future posts it covers.
    - `old_posts` integer: Subscriptions: also this many of your latest posts.
    - `delay` 0 | 5 | 10 | 15 | 20 | 30 | 40 | 50 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 360 | 420 | 480 | 540 | 600: Subscriptions: minutes after a post goes up before it starts.
    - `expiry` string, date: Subscriptions: the last day (optional, up to a year ahead).
  - `dry_run` boolean
  - `details` object: Done-for-you services only: the answers to the service’s `form` (key → text; image fields → upload id).

## Response `200`

Dry run answer — or a replay of an earlier order with the same Idempotency-Key (`replayed: true`).

- object
  - `dry_run` unknown
  - `quote` Quote
    - `service` integer
    - `quantity` integer: The units charged: the quantity (× runs), the comments or usernames sent, or max × posts.
    - `pricePer1k` string: Price per 1,000. USD as a decimal string.
    - `total` string: What the order costs. USD as a decimal string.
    - `currency` 'USD'
  - `balance` string: Your balance. USD as a decimal string.
  - `sufficient` boolean
  - `text_review` boolean: Our team may check the text before the order starts (it is placed and charged, then waits).

## Other responses

- `201`: Placed and charged.
- `400`: The request is not valid. `error.message` says why.
- `401`: No valid API key or session.
- `402`: Balance too low for this order.
- `403`: Refused by this key's safety rails (scope, platforms, caps) or session-only.
- `413`: The request body is too big (uploads up to 4 MB, everything else up to 64 KB).
- `429`: Slow down: too many requests in a short time. Wait `Retry-After` seconds and carry on.

---

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