isError: true.
Always inspect the tool result, then use structuredContent.code and the
associated fields rather than parsing rendered prose.
Common recovery patterns include:
- correct a validation field and call again;
- call
get_statusafter a wrong-account response; - re-read a versioned noun after a revision conflict;
- preserve per-seller or per-source outcomes from a partial result; and
- re-read after
partialWrite: truebefore deciding whether to retry.
null. Pass
null explicitly for a blank value on a nullable input; omitting the input
still returns a validation error. Inputs that do not allow null reject it.
An INVALID_REQUEST with the message “Request declined by platform policy.” and
details.reason of safety_refused means the platform safety policy declined
the request. Revise it and retry, or contact support to ask for a review. See
Request declined by platform policy.
A seller changed the media buy
When you update or cancel a media buy, the seller can refuse the change because it changed the buy after the version you last read. Apostra reads the buy again and compares it with the version your change was based on:- If the seller changed only fields your update does not set, Apostra sends your update once more on the current version. You see a normal result and no conflict.
- If the seller changed a field your update sets, or Apostra cannot tell, you get
a
CONFLICTwith recoverycorrectable. The seller that refused did not apply the change. Apostra never retries a change that overlaps, and it retries at most once.
CONFLICT tells you about the sellers that refused the change. It is not a
statement about every seller. A change to a media buy that spans several sellers
is not atomic, so the other sellers may have applied it, refused it, or failed
in a way that leaves the outcome unknown, such as a timeout. Read
details.per_source for each seller’s outcome, and read the current media buy,
before you send anything again. Resend the change only for sellers that did not
apply it. Do not resend the whole request unless per_source shows that every
seller refused it. When some sellers applied the change and another refused, the
result is not a CONFLICT: it is a SERVICE_UNAVAILABLE error with
details.reason of partial_update and the same per_source list.
After a CONFLICT, read the media buy again, decide whether your change still
applies to what the seller now holds, and send it again if it does. When an
Apostra storefront answers an AdCP update_media_buy directly, the error’s
details.snapshot is usually the media buy after the storefront read it again,
so you can decide without a second call. The snapshot is optional: when it is
absent, read the media buy yourself before you decide. A cancel that an Apostra
storefront queued on your behalf sends itself again on its own with the current
version, and it is done if the seller already holds the buy as canceled,
rejected or completed.
A CONFLICT whose details.error_code names another cause is a different state
conflict. Read the message and the per-source details for what to do.
NOT_FOUND can intentionally hide whether an object exists outside the active
account. Do not treat it as evidence about another account.
An ACCESS_DENIED with details.reason of switch_account_required means the
object, such as an advertiser, belongs to another account you are a member of,
not the account the call acted in. details.owningCustomerId is that account’s
id. Send the call again with it as accountId; on v2, call customer_switch
with it first. An object in an account you do not belong to is refused without
naming the account.
A buyer agent refused on an advertiser gets the reason in details.reason.
Most refusals also use the reason as the error’s message, kept for clients
that match on it. The suggestion is the human-readable text: in
details.suggestion, suggestion on an MCP tool error, and the first of
suggestions through api_call.
LIVE_PROVIDER_UNAVAILABLE from get_delivery with
report: "live_campaign_delivery" means the campaign exists but has no media
buy live at a provider, including a campaign whose buys are still waiting to
start. See
Reporting pipeline
for the buy states it lists, and for the SERVICE_UNAVAILABLE a provider’s
refusal of a started campaign’s read returns instead of a validation error.
Full error reference
Review the canonical error envelope, status mapping, retry behavior, and
troubleshooting guidance shared with stable v2.