OPENADS ERRORS & RECOVERY
2026-10-12 / advertiser agents

Scope
This guide covers campaign preparation, approved funding, activation and
performance reads on Arc (5042) and Base (8453), through SDK or direct HTTP.
The website's error-ux.js is the shared recovery policy. The SDK bundles the
same file as sdk/error-ux.cjs; the API uses it in its existing error handler.
The API's existing authentication, validation, review and financial controls
remain authoritative. The SDK is not a replacement for server protection.

1. Read the result
HTTP failure: preserve status and the openads.error/2.0 body. SDK failure:
catch the exception and use error.toJSON(). Both provide error, message,
next_action and retryable. HTTP also provides retry_after; SDK errors include
status, retry_after, operation_id, campaign_id, stage and tx_hash when known.
Balance details include required/available/shortfall amounts. _micro fields
are integer six-decimal USDC; _native_wei fields are 18-decimal native units.
Never treat an absent amount as zero or expose a raw provider exception.
An unknown error means STOP_AND_REVIEW_ERROR, not permission to pay again.

2. Check whether any transaction already exists
Before acting on any error, inspect the same operation's journal and saved
approval/deposit hashes. Preserve campaign ID, funding intent/ref, command
idempotency keys and signed transaction records. If payment might have been
sent, check the existing hash and campaign first. An error after deposit is
not proof of nonpayment. An earlier USDC approval may already have cost gas.
Never create a new deposit, operation or journal to fix an uncertain payment.

3. Follow the recovery instruction
- ADD_USDC_AND_RETRY_SAME_OPERATION: INSUFFICIENT_USDC_BALANCE. Show chain,
  required amount, current USDC and exact shortfall. Request funds on that
  chain, then continue the same operation and valid approval. The failed
  signing step produced no new transaction; earlier steps may have completed.
- ADD_NATIVE_GAS_AND_RETRY_SAME_OPERATION: INSUFFICIENT_GAS_BALANCE or wallet
  INSUFFICIENT_FUNDS. Request native gas funds on the approved network.
- REQUEST_WALLET_SIGNATURE: signing was cancelled (4001/ACTION_REJECTED or
  WALLET_SIGNATURE_REJECTED). Get consent before requesting another signature.
- CONNECT_OWNER_WALLET / CONNECT_APPROVED_NETWORK: connect the campaign owner
  and approved chain. Do not change a funding intent's chain or wallet.
- FINISH_EXISTING_OPERATION: STATE_BUSY/WALLET_BUSY or a wallet prompt is open.
  Complete that operation. After a crash, confirm the process stopped before
  removing only a stale .lock; never delete/reset the journal.
- SIGN_IN_WITH_OWNER_WALLET: session missing/expired (401). Sign in as the
  owner and retry the same request once. The SDK performs this once for
  V2_SESSION_REQUIRED/EXPIRED. Do not retry other 401 errors as session expiry.
- REVIEW_AND_SIGN_CURRENT_COMMAND: command signature required, expired or
  invalid. Read the current campaign/version and reviewed payload, get consent
  as needed and sign the correct command. Never replay a different payload
  under an existing idempotency key.
- FIX_INPUT_AND_GET_APPROVAL: malformed JSON/input/URL/image/amount, missing
  assets, minimum/maximum budget or oversized body (400/413/422). Correct the
  identified input once; changed campaign/costs require approval. Use editable
  drafts where supported. Already-submitted drafts cannot simply be edited.
- PREPARE_AND_GET_NEW_APPROVAL: campaign, version, pricing or approval changed.
  Resolve existing payments before preparing the new approved operation.
- PREPARE_NEW_CAMPAIGN: CAMPAIGN_ASSET_EXPIRED. Reupload only if the draft is
  still editable; otherwise prepare a new campaign and obtain approval. Never
  repay a campaign with an unresolved payment.
- SELECT_SUPPORTED_NETWORK_AND_GET_APPROVAL: unsupported/unavailable selected
  network. Read current policy, offer an enabled network and obtain approval.
  Do not silently switch Arc/Base or use credit from the wrong chain.
- CHECK_RESOURCE_AND_OWNER: not found (404). Verify the ID and owner session.
  A resource not visible to this wallet must not be accessed via another ID.
- REVIEW_EXISTING_OPERATION: changed input for the same operation ID or an
  IDEMPOTENCY_CONFLICT. Recover the original request; do not invent a new key
  to hide a mismatch or bypass a denied command.
- READ_CURRENT_STATE_BEFORE_CONTINUING: state conflict/closed/ended/noneditable
  campaign or expired resource (409/410). Read once and explain the actual
  state. Do not assume that changing identifiers makes the command valid.
- WAIT_FOR_SETTLEMENT: ended campaign activity is still settling. Keep the
  same campaign and launch operation; check later before further payment.
- REVIEW_PAYMENT_BEFORE_RETRY: simulation failed. Check balances, allowance,
  approved network and payment data. No automatic replacement or repayment.
- CHECK_EXISTING_TRANSACTION: uncertain send, nonce conflict or pending
  receipt/confirmations/finality. Check the saved hash on its original chain.
  A signing SDK may rebroadcast only the identical saved signed bytes.
  A direct HTTP/browser integration must use its existing payment recovery.
- REVIEW_EXISTING_PAYMENT: reverted transaction, expired/closed/changed
  funding, reorg/finality conflict, or definitive 400/409/410/422 during funding
  registration. Show the saved hash and current state; ask for review. Do not
  automatically sign a replacement or create another deposit.
- STOP_AND_REQUEST_REVIEW: forbidden access, blocked campaign, safety hold,
  self-dealing or other 403/423 rejection. Stop and explain the reason. Ask
  the operator to review a safety block; correct legitimate ownership through
  the normal login process. Do not rotate accounts/IPs or change IDs to bypass.
- REQUEST_OPERATOR_SETUP: disabled feature, missing/invalid configuration,
  unavailable signing setup or reviewed payment adapter/configuration. Stop
  spending and request operator setup. HTTP 503 does not always mean retry.
- STOP_AND_REVIEW_ERROR: payment destination/hash/evidence mismatch, excessive
  approved gas, wrong journal, corrupt/local state or an unrecognized failure.
  Preserve records and request review. Never trust provider prose suggesting
  another payment or serialize signed bytes, credentials or the private journal.
- COMPLETE_REQUIRED_VERIFICATION: complete the verification requested by a
  428 response through its supported flow. Do not forge/bypass verification.
- WAIT_AND_RETRY_SAME_OPERATION / RETRY_SAME_OPERATION: temporary API/RPC
  outage, rate limit or lost response. Follow the bounded retry rules below.

4. Bound retries
retryable=true allows repeating the same request/operation, not spending again.
Honor HTTP Retry-After first (seconds or HTTP date), then retry_after when
provided. Never shorten that wait. Without a delay, use 10, 30, 60 seconds for
at most three automatic retries, then show pending/error and await another
user request. Do not reset the retry counter on each callback or nested step.
For long Retry-After delays, show when the user can resume instead of keeping
a process awake. No continuous polling, new background AI or parallel attempts.
Read only the existing campaign or hash when confirmation is pending.
retryable=false means user/operator action or review is required first. It
does not prevent continuing the same operation after funds/consent are supplied.
Do not retry a permanently denied command or unknown error automatically.

5. Handle non-error states too
prepare ready=false / WAIT_FOR_REVIEW_OR_FIX_CREATIVE: show review/change
requirements. Do not launch or pay until every selected surface is approved.
REVIEW_REQUIRED_NO_ADDITIONAL_PAYMENT: explain review outcome; no new deposit.
COMPLETE_PAYMENT_IN_BROWSER: hand off the same campaign to the existing website.
RETRY_SAME_LAUNCH_AFTER_APPROVAL_CONFIRMATION: check the existing approval.
RETRY_SAME_LAUNCH_AFTER_DEPOSIT_CONFIRMATION: check the existing deposit.
RETRY_SAME_LAUNCH_TO_REGISTER_EXISTING_TRANSACTION: register that same hash.
RETRY_SAME_LAUNCH_WITH_APPROVAL: resume the same operation and saved approval.
WAIT_FOR_ACTIVATION / GET_CAMPAIGN_LATER: payment/activation is pending. Read
the same campaign later; do not fund again. Report payment_error when present.
Only say live when campaign status is ACTIVE and every selected surface is
active. Partial activation or unavailable performance is not full success.
Return ID, actual state, existing hash and owner-login dashboard link.
Performance reads do not pay. Unknown metrics stay null, not invented zeroes.
Advertising deposits are non-refundable; settled unused funds are ad credit.

6. Arc and Base payment preflight
Both use pinned official six-decimal USDC and the reviewed advertising Vault.
The standard wallet adapter checks USDC before approval and before deposit.
Arc native gas is USDC; a deposit's native balance must cover transferred USDC
plus gas. Base native gas is ETH; its check includes the current L1 fee estimate.
The approved per-transaction execution cap excludes Base L1 fees. Approval and
deposit are separate steps. If deposit is denied after approval, report both
facts: approval may have succeeded, but no new deposit was signed by that step.
Balances/fees may change after preflight. Keep subsequent receipt/error checks.

7. Direct HTTP without the campaign SDK
Use the same auth, draft, review, funding and campaign endpoints described in
integration.txt. Read API error fields and use the recovery instructions above.
The server validates inputs/access/review/financial records, but cannot inspect
an external wallet's cancelled prompt or promise it has funds before signing.
Your wallet integration must report those local failures too. You can reuse
the bundled createEthersWallet adapter without the campaign client: verify
pinned funding data, call preparePayment only after approval, durably save its
signed packet before broadcast, then submit that exact hash. Preserve the same
intent/ref and private journal. Alternatively use the existing website handoff.
Never use a bare API 202 response or a chain receipt as proof that ads are ACTIVE.

Verification scope
Arc/Base denial, insufficient funds, signing, recovery, request limits and
direct HTTP error envelopes are checked with isolated tests. Production Arc
Website Ads and Base Website Ads Center Popup (300X250) paid activation and
performance have been verified separately. Base verification also covers
exact-shortfall funding, campaign/channel ACTIVE, owner dashboard reads and
retry without another signature or broadcast. Base actual balance-shortage
handling was checked separately without signing or sending. Other Base
formats and Share/Earn agent paid activation are not proven by these checks.
