Skip to main content

Batches

Up to 200 drafts of one kind in one call, written within 8 hours at half the standard rate

A batch sends many drafts of one kind in a single call. S'more writes them on GPU runs shared by every workspace, finishes each item within 8 hours and charges half the writer's standard rate. Each item becomes an ordinary draft that you read, pick from and post or send yourself. S'more posts and sends nothing.

When to use a batch​

Use single drafts when a person is waiting for the result. A single draft starts as soon as a GPU is up and takes minutes.

Use a batch when the work can wait a few hours, such as replies to fifty threads for tomorrow or an email for everyone on a list. A batch starts within 2 hours, or right away if a GPU run is already going, and every item is written within 8 hours. Each item costs half as much, and batch items do not count toward the single-draft limits.

A batch takes every kind of draft. All its items share one platform and one type:

platformtypeItem fieldsWriter
redditpostsubreddit, plan, confirm_rules_allow_aiember-v1, ember-14k, ember-28k
redditreplysubreddit, thread, goal, factsember-reply-v1
xposttopic, facts, audiencex-writer-v1
xreplythread, goal, factsx-reply-v1
emailoutreach, follow_up, replyto, from, goal, facts, thread, length_wordsprose-1
newsletter, blogposttopic, facts, audience, outline, title, length_wordsprose-1
newsletter, blogrewritesource_text, instructions, keep_linksprose-1

Each item takes the fields of a single draft of that kind, with the same rules, less platform, type, model and idempotency_key, which the batch sets once. An item may also carry count.

How scheduling works​

Batch items from every workspace wait in one queue. The Reddit and X writers share one GPU pool and prose-1 has its own, and each pool follows the same rules:

  1. When you submit, S'more stores the batch with a deadline_at 8 hours later, and its items join the queue.
  2. If a GPU run is already going on the pool, the items ride it and start writing soon after. A run started for single drafts takes batch items while it writes those drafts and for a few minutes after, then stops; items it did not reach keep waiting for a batch run.
  3. Otherwise S'more holds the items so more work can share one GPU start. A run starts when the oldest waiting item is 2 hours old, or sooner once 200 sends are waiting on the pool. Everything queued rides that run.
  4. Single drafts go first on every run, so a person waiting on one waits at most for one batch item to finish.

Most items are written long before the deadline. One blog post sent at 10:00 with nothing else queued starts writing at 12:00 and is ready by about 12:10.

The hours after the hold leave room for retries. If no GPU starts, or the day's batch GPU budget is used up, the items keep waiting and S'more tries again until the deadline. Batches have their own GPU budget, so they never use up the time single drafts share. A batch item never fails with gpu_daily_cap, gpu_start_timeout or gpu_refused, and the 6-hour limit that expires a single draft does not apply to it.

An item that is not written by deadline_at ends failed with error.code batch_deadline_missed, and its credits are refunded in full. An item that is already writing at the deadline finishes.

Submit a batch​

POST /api/v1/drafts/batches needs the reddit:posts:write scope. This batch asks for replies to three X threads:

curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<JSON | tee batch.json
{
"platform": "x",
"type": "reply",
"idempotency_key": "replies-$(date +%s)",
"items": [
{
"thread": [{ "from": "Original post", "body": "Anyone found a good way to see which subreddits talk about their product?" }],
"goal": "Answer helpfully and mention that mention trackers can do this",
"facts": ["A mention tracker counts a term in one subreddit across its full history"]
},
{
"thread": [{ "from": "Original post", "body": "How do you give an agent access to Reddit data?" }],
"goal": "Answer the question and mention that the S'more API has an MCP server",
"facts": ["Reddit mentions, signals and top posts are available as MCP tools"]
},
{
"thread": [
{ "from": "Original post", "body": "We launched last week and nobody is talking about us yet." },
{ "from": "Reply", "body": "Where are you even looking?" }
],
"goal": "Suggest tracking mentions from before a launch to after it",
"facts": ["Reports show the share of active people who used the term each month"]
}
]
}
JSON

It answers at once:

{
"schema_version": 2,
"batch_id": "8c1f0a52-1d7e-4f43-9a55-0f5b8c9d1e20",
"platform": "x",
"type": "reply",
"model": null,
"state": "queued",
"submitted_at": "2026-10-25T19:00:00Z",
"deadline_at": "2026-10-26T03:00:00Z",
"items": 3,
"price_percent": 50,
"credits_deducted": 1386,
"poll_after_s": 600,
"drafts": [
{ "index": 0, "draft_id": "1b6f3e2a-7c4d-4e8f-9a1b-2c3d4e5f6a70" },
{ "index": 1, "draft_id": "5d2a9c71-0b3e-4f6a-8d1c-7e9f0a2b3c41" },
{ "index": 2, "draft_id": "9e4b1d83-2c5f-4a7b-b0e2-8f1a3c5d7e92" }
]
}

Request fields​

FieldTypeRules
platformstringRequired. The platform of every item
typestringRequired. The type of every item
idempotency_keystringRequired, with the same rules as a draft's key. The same key with the same items returns the stored batch and charges nothing; the same key with different items answers 409 idempotency_conflict
modelstringOptional. The writer for every item, from the models a single draft of this kind takes. Leave it out for the default
itemsarrayRequired. 1 to 200 items, each with the fields of a single draft of this kind and an optional count

Answer fields​

FieldMeaning
batch_idThe batch's id, for reading it
platform, type, modelAs you sent them. model is null when you left it out
statequeued until an item starts writing
submitted_at, deadline_atWhen S'more stored the batch, and when every item must be written by: 8 hours later
itemsHow many items the batch holds
price_percentThe share of the standard rate this batch pays. It is stored with the batch, so a later price change never reprices it
credits_deductedWhat the batch took when you submitted: the most every item could cost at the batch rate
poll_after_sSeconds to wait before the first read
draftsEach item's index, in the order you sent them, with its draft_id

For these three replies, credits_deducted is each item's 16 candidates at their 384-token limit plus the prompt, at the batch rate: about 1,386 credits (about $1.39 at list) at today's rates. Each item then settles at the tokens it used and the rest is refunded.

Submit over MCP​

smore_draft_batch takes the same arguments: platform, type, an optional model, idempotency_key and items. It returns the same answer as structured content.

curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- <<JSON | sed -n -e 's/^data: //' -e '/^{/p' | jq '.result.structuredContent | {batch_id, state, deadline_at, credits_deducted}'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "smore_draft_batch",
"arguments": {
"platform": "x",
"type": "reply",
"idempotency_key": "mcp-replies-$(date +%s)",
"items": [
{
"thread": [{ "from": "Original post", "body": "Anyone found a good way to see which subreddits talk about their product?" }],
"goal": "Answer helpfully and mention that mention trackers can do this",
"facts": ["A mention tracker counts a term in one subreddit across its full history"]
},
{
"thread": [{ "from": "Original post", "body": "How do you give an agent access to Reddit data?" }],
"goal": "Answer the question and mention that the S'more API has an MCP server",
"facts": ["Reddit mentions, signals and top posts are available as MCP tools"]
}
]
}
}
}
JSON

An agent connected with OAuth calls the tools by name. A good instruction is: "Send these 30 threads to smore_draft_batch as X replies, then check smore_get_draft_batch every poll_after_s seconds until it is done."

Read a batch​

GET /api/v1/drafts/batches/{id} needs reddit:posts:read and is free. Read it every poll_after_s seconds until state is done:

BATCH_ID=$(jq -r .batch_id batch.json)
curl -s "https://app.makesmores.com/api/v1/drafts/batches/$BATCH_ID?limit=25" \
-H "Authorization: Bearer $SMORE_API_KEY" \
| jq '{state, counts, poll_after_s, next_after}'
{
"schema_version": 2,
"batch_id": "8c1f0a52-1d7e-4f43-9a55-0f5b8c9d1e20",
"platform": "x",
"type": "reply",
"model": null,
"state": "writing",
"submitted_at": "2026-10-25T19:00:00Z",
"deadline_at": "2026-10-26T03:00:00Z",
"finished_at": null,
"counts": { "total": 3, "queued": 0, "writing": 1, "ready": 2, "failed": 0 },
"price_percent": 50,
"poll_after_s": 30,
"items": [
{
"index": 0,
"draft_id": "1b6f3e2a-7c4d-4e8f-9a1b-2c3d4e5f6a70",
"state": "ready",
"error": null,
"options": [
{
"option": "A",
"model": "x-reply-v1",
"body": "A mention tracker does this. It counts a term in one subreddit across its full history, so you can see where people bring you up.",
"words": 25,
"facts": { "local_check": "pass", "added_numbers": [], "missing_numbers": [], "missing_names": [] }
}
],
"choice": null
},
{ "index": 1, "draft_id": "5d2a9c71-0b3e-4f6a-8d1c-7e9f0a2b3c41", "state": "ready", "error": null, "options": [{ "option": "A", "...": "..." }], "choice": null },
{ "index": 2, "draft_id": "9e4b1d83-2c5f-4a7b-b0e2-8f1a3c5d7e92", "state": "writing", "error": null, "options": [], "choice": null }
],
"next_after": null,
"fact_check": { "checked_by_smore": "numbers_and_names", "how": "..." },
"notice": "...",
"content_notice": "..."
}
FieldMeaning
statequeued until an item starts, writing while any item is open, done once every item is ready or failed
countsItems by state: total, queued, writing, ready and failed
finished_atWhen the batch reached done, or null
price_percentThe share of the standard rate the batch pays
poll_after_sSeconds to wait before the next read
itemsThis page of items in index order. Each has its index, draft_id, state (queued, writing, ready or failed), error with its code when it failed, options, the same options a single draft of this kind returns, and choice once a pick is recorded
next_afterThe after for the next page, or null on the last page
fact_check, notice, content_noticeThe rubric for checking each option before you show it, and the notices a draft read carries

Read every page​

Items come in pages by index. after is an item index, and the read returns the items after it: the default -1 starts at the first item. limit is 25 by default and at most 100. Pass next_after back as after until it is null:

BATCH_ID=$(jq -r .batch_id batch.json)
after=-1
while :; do
page=$(curl -s "https://app.makesmores.com/api/v1/drafts/batches/$BATCH_ID?after=$after&limit=100" \
-H "Authorization: Bearer $SMORE_API_KEY")
echo "$page" | jq -c '.items[]? | {index, state, first_option: .options[0].body}'
after=$(echo "$page" | jq -r '.next_after // empty')
if [ -z "$after" ] || [ "$(echo "$page" | jq '.items | length')" = 0 ]; then break; fi
done

To wait for the whole batch, read one item at a time until state is done. This can take up to 8 hours:

BATCH_ID=$(jq -r .batch_id batch.json)
while :; do
read=$(curl -s "https://app.makesmores.com/api/v1/drafts/batches/$BATCH_ID?limit=1" \
-H "Authorization: Bearer $SMORE_API_KEY")
[ "$(echo "$read" | jq -r .state)" = done ] && break
sleep "$(echo "$read" | jq -r '.poll_after_s // 60')"
done

Read over MCP​

smore_get_draft_batch takes batch_id and an optional after and limit, and returns the same read:

jq -n --arg id "$(jq -r .batch_id batch.json)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_get_draft_batch", arguments: {batch_id: $id, limit: 25}}}' \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent | {state, counts, next_after}'

Pick and post​

Each item is an ordinary draft. GET /api/v1/drafts/{id} or smore_get_draft with its draft_id returns its full read, with the platform's block, fact_check and, for Reddit, ai_policy and open_url. Record the pick with POST /api/v1/drafts/{id}/choice or smore_choose_draft, as for any draft, and the console lists batch items with your other drafts. Reading a draft and recording a choice are free.

DRAFT_ID=$(jq -r '.drafts[0].draft_id' batch.json)
curl -s "https://app.makesmores.com/api/v1/drafts/$DRAFT_ID/choice" \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"option": "A"}'

The person then copies the option they picked into X, Reddit or their email.

Examples​

Each example writes the batch body to a file, sends it over REST, then sends the same body over MCP with a fresh key. Over MCP the body is the tool's arguments. Every batch here costs credits at the batch rate.

X replies​

Take up to ten fresh posts worth a reply from X signals and reply to all of them in one batch. The jq step drops links, bare domains and brackets from each post and keeps its first 1,000 characters, since no thread message may hold a link or a [slot]. It falls back to one sample post when none come back. X replies does the same for a single draft.

curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "smore_find_x_posts", "arguments": {"worth_reply_only": true, "limit": 10}}}' \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq --arg key "fresh-replies-$(date +%s)" \
--arg fact "Mention trackers count a term in a subreddit across its full history" '
[.result.structuredContent.posts[]?.text_untrusted // empty
| gsub("https?://\\S+"; "") | gsub("\\S+\\.[a-z]{2,}\\S*"; "") | gsub("[\\[\\]<>]"; "") | .[0:1000]
| select(test("[A-Za-z]"))]
| if length == 0 then ["What tools do you use to find customers?"] else . end
| {platform: "x", type: "reply", idempotency_key: $key,
items: [.[] | {thread: [{from: "Original post", body: .}], goal: "Add one useful point to the conversation", facts: [$fact]}]}' \
> x-replies-batch.json
curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @x-replies-batch.json
jq --arg key "mcp-fresh-replies-$(date +%s)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_draft_batch", arguments: (.idempotency_key = $key)}}' \
x-replies-batch.json \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent | {batch_id, items, deadline_at}'

X posts​

A week of posts, one topic each. The second item asks for two options.

cat > x-posts-batch.json <<JSON
{
"platform": "x",
"type": "post",
"idempotency_key": "week-of-posts-$(date +%s)",
"items": [
{
"topic": "Our public API is open today",
"audience": "Developers who build agents",
"facts": ["One key reaches every product over REST and MCP"]
},
{
"topic": "What we learned reading 1,200 support tickets",
"facts": ["1,200 tickets from September", "41% were about exporting data"],
"count": 2
},
{
"topic": "Why we price drafts per token",
"facts": ["Writers bill per token, counting every candidate", "A failed draft is refunded in full"]
}
]
}
JSON
curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @x-posts-batch.json
jq --arg key "mcp-week-of-posts-$(date +%s)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_draft_batch", arguments: (.idempotency_key = $key)}}' \
x-posts-batch.json \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent | {batch_id, items, deadline_at}'

Reddit posts​

Two plans for r/running. With model left out, each item gets one option from each writer, labelled A, B and C with the model hidden until you record a choice, and counts as three sends toward the limits.

cat > reddit-posts-batch.json <<JSON
{
"platform": "reddit",
"type": "post",
"idempotency_key": "running-posts-$(date +%s)",
"items": [
{
"subreddit": "running",
"plan": {
"format": "personal experience, text only",
"length_words": 120,
"angle": "Cut a 10k time by four minutes in twelve weeks by adding one interval session a week",
"points": [
{ "point": "Added one interval session a week", "evidence": "6 x 800m at 5k pace every Tuesday" },
{ "point": "Ran a faster 10k", "evidence": "48:10 down to 44:05" }
],
"author_specifics": ["Started running two years ago"],
"closing": "ask readers what single change helped their 10k most"
}
},
{
"subreddit": "running",
"plan": {
"format": "question, text only",
"length_words": 90,
"angle": "Asking how others fit long runs into a week with two young kids",
"points": [
{ "point": "Long runs now start at 5:30 on Saturdays", "evidence": "back home by 7:30" },
{ "point": "Weekday runs moved to lunch breaks", "evidence": "three 40-minute runs" }
],
"author_specifics": ["Two kids under four"],
"closing": "ask what schedules have worked for other parents"
}
}
]
}
JSON
curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @reddit-posts-batch.json

Over MCP, this one pins ember-v1 for the whole batch, so each item is one send and returns up to count options from that writer:

jq --arg key "mcp-running-posts-$(date +%s)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_draft_batch",
arguments: (.idempotency_key = $key | .model = "ember-v1" | .items |= map(.count = 2))}}' \
reddit-posts-batch.json \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent | {batch_id, model, items, deadline_at}'

Read each item's draft before posting. Its ai_policy and rules_to_check_untrusted say what to confirm with the person. A subreddit whose rules may ban AI-written posts needs confirm_rules_allow_ai: true on that item, as on a single draft.

Reddit replies​

Each item is a subreddit and a thread, oldest first, as for one Reddit reply:

cat > reddit-replies-batch.json <<JSON
{
"platform": "reddit",
"type": "reply",
"idempotency_key": "running-replies-$(date +%s)",
"items": [
{
"subreddit": "running",
"thread": [
{ "from": "slow_and_steady", "title": "How did you pace your first half marathon?", "body": "Race is in six weeks and I have no idea what pace to start at." },
{ "from": "trail_tom", "body": "Start a little slower than goal pace and pick it up after 15 km." },
{ "from": "slow_and_steady", "body": "What if I don't really have a goal pace yet?" }
]
},
{
"subreddit": "running",
"thread": [
{ "from": "new_to_this", "title": "Shin pain after two weeks of running", "body": "Is this normal or should I stop?" }
]
}
]
}
JSON
curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @reddit-replies-batch.json
jq --arg key "mcp-running-replies-$(date +%s)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_draft_batch", arguments: (.idempotency_key = $key)}}' \
reddit-replies-batch.json \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent'

Emails​

One cold email for each person on a list, from the same sender. Every item has its own to, goal and facts. Newsletters and blog posts, written or rewritten, batch the same way with their own platform and type.

cat > emails-batch.json <<JSON
{
"platform": "email",
"type": "outreach",
"idempotency_key": "wholesale-list-$(date +%s)",
"items": [
{
"to": { "name": "Priya Shah", "role": "Head of Growth", "company": "Northwind Coffee" },
"from": { "name": "Sam Lee", "company": "Roastline" },
"goal": "Ask for a short call about wholesale beans for their cafes",
"facts": ["Roastline roasts to order every Tuesday and Friday", "Northwind opened its third cafe this month"]
},
{
"to": { "name": "Tom Okafor", "role": "Owner", "company": "Corner Bakehouse" },
"from": { "name": "Sam Lee", "company": "Roastline" },
"goal": "Offer a free sample box of espresso beans",
"facts": ["A free sample box holds three 250 g bags", "Wholesale orders ship within two days of roasting"],
"length_words": 70
}
]
}
JSON
curl -s https://app.makesmores.com/api/v1/drafts/batches \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-d @emails-batch.json
jq --arg key "mcp-wholesale-list-$(date +%s)" \
'{jsonrpc: "2.0", id: 1, method: "tools/call", params: {name: "smore_draft_batch", arguments: (.idempotency_key = $key)}}' \
emails-batch.json \
| curl -s https://app.makesmores.com/api/v1/mcp \
-H "Authorization: Bearer $SMORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- \
| sed -n -e 's/^data: //' -e '/^{/p' \
| jq '.result.structuredContent | {batch_id, items, deadline_at}'

Price​

A batch pays half the writer's standard per-token rate. S'more stores that share with the batch as price_percent when you submit, so a price change after that never reprices it. As for single drafts, the submit deducts the most each item could cost, each item settles at the tokens it used and is rounded up once with the usual 1-credit minimum, and a failed item is refunded in full.

SlugWhat it doesInput / 1MBatch input / 1MOutput / 1MBatch output / 1MStatus
ember-v1Reddit post writer$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
ember-14kReddit post writer, 14k$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
ember-28kReddit post writer, 28k$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
ember-reply-v1Reddit reply writer$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
x-writer-v1X post writer$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
x-reply-v1X reply writer$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive
prose-1Email, newsletter and blog writer$55,000 credits$2.502,500 credits$150150,000 credits$7575,000 creditsLive

An X reply that used 179 input and 550 output tokens costs 84 credits ($0.084 at list) as a single draft and 42 credits ($0.042 at list) in a batch.

ItemTokensSingle draftIn a batch
X reply179 in, 550 out84 credits ($0.084 at list)42 credits ($0.042 at list)
50 X replies179 in, 550 out each4,200 credits ($4.20 at list)2,100 credits ($2.10 at list)
Reddit post, three writers1,050 in, 8,880 out1,338 credits ($1.34 at list)669 credits ($0.669 at list)
prose-1 email, 8 candidates500 in, 800 out123 credits ($0.123 at list)62 credits ($0.062 at list)

GET /api/v1/models shows each writer's batch rate in price.batch, and Credits has the formula.

Prices on this site were read from GET /api/v1/models on 2026-10-26.

Limits​

LimitValue
Items per batch1 to 200, all with one platform and type
Request body1 MiB; send a larger set as more than one batch
Open batch sends per workspace600
Open batch sends across S'more1,000 on each GPU pool

A send is one writing job on a GPU. A Reddit post item without model is three sends, one per writer, and every other item is one. An item counts while it is queued or writing. A batch that would take either count over its limit answers 429 batch_queue_full and stores nothing; send it again later.

Batch items do not count toward the single-draft limits (5 drafts open at once per workspace), so a batch never blocks single drafts. Rate limits has every limit.

Errors​

S'more checks each item with the same rules and codes as a single draft. If any item fails, the answer is that item's code with item set to its index, and nothing is stored or charged. Over MCP the tool error's message starts with the index instead, as in Item 7: The request breaks the content rules.:

{
"code": "content_invalid",
"message": "The request breaks the content rules.",
"item": 7,
"details": [{ "field": "thread[0].body", "rule": "no_link" }]
}
StatusCodeMeaning
400invalid_requestA missing or unknown field, a duplicate key or a null, in the batch or in an item
400model_coming_soonThat writer is coming soon. Nothing was stored or charged
402credits_requiredThe batch's deduction, every item's most possible cost added up, is more than the workspace or the key's cap allows. Nothing was stored
404batch_not_foundNo batch with that id in this workspace
409idempotency_conflictThat key was used for a batch with different items. Send a new key for new work
409drafts_offDrafting or batches are switched off for now. If batches are switched off while items wait, those items fail with drafts_off and are refunded
409, 422An item's code, with itemThe codes a single draft answers, such as ai_policy_unconfirmed, plan_invalid, email_invalid or content_invalid
429batch_queue_fullToo much batch work is waiting, in this workspace or across S'more. Nothing was stored. Send the batch again later

A failed item has state: "failed" and an error.code: batch_deadline_missed when it was not written by deadline_at, or a single draft's failure code such as no_clean_draft. Every failed item is refunded in full. Errors lists the codes for every route.