Scheduled run body: unknown fields are silently dropped, not a 400

A typo in a Sume scheduled run body is dropped without an error, unlike a Format run. Check names, then read the receipt to see what applied.

4 min readSume
All posts

The body of a Sume scheduled run accepts a fixed list of properties and nothing else, and unknown top-level properties are silently dropped, not rejected. A misspelled generation_spend_cap_usd or webhook_url does not return a 400; the run starts without it. A Format run behaves the other way: unknown top-level fields are 400 unknown_parameter, with a suggestion when the name is close. If you port a body between the two surfaces, check the field names yourself.

Which fields does a scheduled run take?

These are the documented properties. Anything outside the list is ignored.

Scheduled run body fields, from docs.sume.com/agents/actions/api-trigger (read 2026-10-03)
FieldDefaultNotes
input{}Caller data: at most 64 properties and 2097152 UTF-8 bytes
on_active_runskipskip or reject; Format runs default to allow
generation_spend_cap_usdThe schedule's capClamped to the lower of request and schedule cap; null runs without the automation ceiling; 0 is 400
primary_output_keyThe schedule's defaultUp to 64 characters
output_schemaThe schedule's default{ name, strict, schema } per-request override
response_formatNoneOpenAI-shaped alias for output_schema
communication.modeasyncDescriptive; the URL is what arms delivery
communication.webhook_urlNonePublic HTTPS URI up to 2048 characters; callback_url is an accepted alias

What does a dropped typo cost you?

The failure is quiet. A misspelled cap means the schedule's own cap applies, which is $1.00 per run when none was set. A misspelled webhook_url means no terminal delivery is armed, so a service waiting for the callback waits forever. A misspelled on_active_run leaves the default skip, so an overlap that you wanted to surface as 409 action_run_in_progress comes back as a 200 skipped receipt.

None of these produces an error code, which is why the receipt is the place to verify.

How do I catch it?

Read back what the receipt says applied. usage.generation_spend_cap_usd_micros shows the cap in force, output_schema.source shows whether your override took (request_override) or the schedule's binding did (action_default), and trigger.idempotency_key echoes the key. A run that started with the wrong cap or schema is visible on the first receipt.

A cheap guard is a client-side allowlist that mirrors the table above and throws on any other key before the request leaves your process.

import json

ALLOWED = {"input", "on_active_run", "generation_spend_cap_usd", "primary_output_key",
           "output_schema", "response_format", "communication"}

def check(body):
    unknown = set(body) - ALLOWED
    if unknown:
        raise ValueError(f"unknown scheduled-run fields: {sorted(unknown)}")
    return body

print(json.dumps(check({"input": {"campaign": "summer"}, "on_active_run": "reject"})))

Should I treat the two surfaces the same?

No. Scheduled and Format runs share receipts and structured output, but not defaults or strictness. Scheduled runs skip an overlap by default and drop unknown fields; Format runs run concurrently by default and reject unknown fields. Copy a body from one to the other only after checking both.

What about the response side?

Errors on the response side are strict, which makes the quiet request side easy to miss. A bad value on a known field is a 400 invalid_request: an input that is not an object, a cap that is not a finite number above zero or null, a webhook_url that is not a public HTTPS URL, or empty Action instructions. A bad schema is 400 output_schema_invalid with details.violations[]. Only the unknown names pass silently, so validate names on your side and values on theirs.

Sources

Related posts

More in Agents

All Agents posts

Written by Sume