Buyer RFPs are part of the buyer beta (the V4 beta feature profile). An account
that is not on the beta is refused with
FEATURE_NOT_ENABLED on every call that
reads or writes an RFP, and an account whose profile cannot be read is refused
with SERVICE_UNAVAILABLE, never let through. Your profile is described in
Accepting a plan sets what your account can do.What an RFP holds
Only the name is required. The thinner the ask, the vaguer the proposals that will come back, so add what you know.flight, budgetRange, channels and geo use AdCP’s own shapes and names, so
they will go to a seller as the matching AdCP offer filters (start_date and
end_date, budget_range, channels, countries and regions) when sending
ships.
Every read returns the same names the save takes, plus these read-only fields:
Every RFP belongs to a plan
A plan is one planning cycle for one advertiser. It is not a billing plan such as Business Manager. When you create an RFP, Apostra makes the plan for you, so you never have to name one. The plan’s ID,planId,
is the AdCP opportunity_id that every request under the plan carries to a
seller, so a seller will see one conversation per plan. The ID is opaque and
never changes. Apostra does not yet let you put a second RFP into an existing
plan or name a plan yourself.
Create a draft
Callsave_buyer_rfp with advertiserId, name and an idempotencyKey. Add
any ask fields you have.
buyerRfp, with action: "created". The
idempotencyKey is yours to choose, 16 to 255 letters, digits and _ . : -. Send
the same key again and you get the same RFP back with replayed: true. Reuse a
key for a different request and the call is refused with a conflict.
Change a draft
Callsave_buyer_rfp with rfpId, the expectedRevision from your last read,
and the fields to change. A field you leave out stays. null clears an optional
field.
- A stale
expectedRevisionis refused as a conflict that names the current revision. Read the RFP again and retry. - Only a draft changes. An RFP that is open or closed refuses the change, and the message tells you to copy it.
- An update takes no
idempotencyKey, noadvertiserIdand noduplicateFromRfpId: the revision is what makes a retry safe.
Copy an RFP into a new draft
Callsave_buyer_rfp with duplicateFromRfpId and an idempotencyKey. The copy
takes the source’s ask, gets a new RFP ID, and gets a new plan, because a
re-run is a new planning cycle. Its name is the source’s name with ” (copy)”, or
the name you send. The source is untouched. Duplicating takes no other ask
fields: copy first, then change the copy.
Read RFPs back
getwithkind: "buyer_rfp"and theidof an RFP returns it.searchwithkind: "buyer_rfp"andfilter.advertiserIdlists that advertiser’s RFPs, newest first, in pages. Narrow it withfilter.rfpStatus. It takes no text query. When a page has more, it returns anextCursor.
NOT_FOUND, the same as one that
does not exist.
What is not here yet
- Opening an RFP to sellers, extending it, closing it and reopening it.
- Proposals arriving on an RFP, and turning them into campaigns.
- Naming a plan, or putting more than one RFP in a plan.