1. Start with seller discovery
Discovery is read-only and safe to run as often as you like.search
save_connection with one intent per call:
2. Give the loop a durable owner
A model’s memory is not a database. Before your agent writes anything, decide where these live:- the person’s request and any approvals they gave;
- the active
customerIdand advertiser id; - every Semicola id you create (
cmp_…,exe_…,sfp1:…,mb_…); - the
idempotencyKeyfor each write you attempted, and whether it finished.
get
before deciding what to do next.
3. Add buying steps
1
Advertiser
save_advertiser with a name, brand domain and primary currency. If a fact is missing you get
needs_input; ask the person, do not guess. Use sandbox: true while you build.2
Draft campaign
save_campaign with the brief, flight, budget and an idempotencyKey. Save the returned
campaignId and revision.3
Request proposals
request_proposals with campaignId, expectedCampaignRevision and a new idempotencyKey. It
returns at once with an execution id and a status of running.4
Collect results
Poll with
get or call request_proposals again with the same key and a resultCursor to page
through what has arrived. Each seller reports quoted, products or failed.5
Refine
refine_proposal with the proposalId and plain instructions, optionally keepProductIds,
dropProductIds or a budgetDelta. The seller may decline parts of the request.6
Stage
save_media_buy with fromProposalId for each proposal the person picked. Nothing is booked.7
Launch, with the person
save_campaign with desiredPhase: "active" returns pending_confirmation. Show the summary;
only after the person approves, call again with confirmLaunch: true. See the Campaign object
guide.Resuming a proposal request
Only one execution runs per buyer at a time. If your process dies mid-request, do not start a new one: callrequest_proposals again with the same idempotencyKey and you get the existing
execution back, including everything that has arrived since.
Recovering from interrupted writes
If a write times out or the connection drops, the write may still have happened. Read the object first. If it is unchanged, retry with the sameidempotencyKey. If it changed, compare it with what
you intended, then decide. After a REVISION_CONFLICT, re-read and re-decide rather than retrying
with a bumped number.
4. Test the boundaries
- Run the whole loop against a sandbox advertiser: sellers answer, buys are placed, delivery is simulated, and no money moves.
- Test the empty cases: no sellers, a seller that fails, an execution where every seller passes.
- Test that your agent stops at
pending_confirmationandneeds_inputinstead of pushing through. - Test resuming after a restart at every step above.
Errors
Codes, partial results and safe retries.
v3 Tool Catalog
Every input field for the tools used here.