This recipe turns a Quotient quote_accepted event into a Drum delivery project with the "Quote Accepted" status and the accepted total recorded as the deal value. It uses three Drum API calls. Endpoint details are in Opportunities API, Reference data API, and API authentication, permissions and rate limits.
Before you start
Create an integration user in Drum with its own role that holds only:
api_readapi_createread_all_projectsupdate_all_opportunitiescreate_projectsview_opportunity_financial_values(needed to sendbudget_cents)
Do not use an admin user. Create an account-scoped API token for that user under Settings, API Tokens, and set an expiry. Put a reminder in your calendar to rotate it.
Store the Drum opportunity number on the quote. Before a quote is sent, put the Drum opportunity number (for example
OPP-2026-014) in the Quotient quote's Order/Reference Number field, the one collected at acceptance time. That number is the only link between the two systems, so make it a required step in your quoting process.Send the event through a step that can add a header. Quotient's native webhooks send no authentication header, so they cannot call Drum directly. On
quote_accepted, run a Zapier "Webhooks by Zapier" action (or your own middleware) that sends:Authorization: Bearer <api-token>
Content-Type: application/json
Step 1: find the opportunity
GET https://<your-drum-host>/api/v1/opportunities?project_number=OPP-2026-014
The response is an array. Take the id of the first item.
If the array is empty, stop the Zap and notify a named person (for example, the sales administrator) with the quote reference. Do not continue and do not create anything. An empty result means the reference number on the quote is missing or wrong, and only a person can fix that.
Step 2: find the "Quote Accepted" status id (once)
GET https://<your-drum-host>/api/v1/project_statuses?type=project
Find the entry whose name is Quote Accepted and keep its id. Status ids do not change, so store it as a constant in the Zap rather than looking it up on every run.
Step 3: convert
POST https://<your-drum-host>/api/v1/opportunities/<id>/convert
{
"project_status_id": 410,
"budget_cents": 4850000,
"expected_project_status_id": 301
}
project_status_id: the "Quote Accepted" id from step 2.budget_cents: the accepted quote total, ex-tax, in cents (an integer).$48,500.00becomes4850000. It is stored on the project and becomes the opportunity's deal value.expected_project_status_id(optional): theproject_status.idfrom the step 1 result. If someone moved the opportunity between step 1 and step 3, Drum refuses with409 stale_staterather than converting a record that changed under you.
Read the response
Response | Meaning | Action |
| The project was created and the opportunity is won | Done |
| A project already exists for this opportunity | Done. Nothing changed |
| The opportunity status changed since step 1 | Stop and notify a person |
| Another request holds the opportunity | Retry with backoff |
| More than 30 converts in a minute | Retry after a minute |
| Drum error | Retry with backoff |
| The token's role lacks | Fix the role, then rerun |
| The opportunity id is wrong or hidden from the token user | Stop and notify a person |
Any other | The opportunity cannot be converted (for example no company client, or linked to a variation); the | Stop and notify a person |
Treat 201 and 200 created: false both as success, so a Quotient retry (Quotient resends at 5, 10, and 15 minutes) or a Zapier rerun never creates a second project.
Retries
Zapier does not replay a step that returned a non-2xx response by default. Either enable Autoreplay on the Zap, or add a path that waits and calls step 3 again for 409 retry_later, 409 rate_limited, 429, and 5xx. Do not retry 4xx responses other than those three codes; they need a person.
Revised quotes
If a quote is revised and accepted a second time, the convert call returns 200 created: false and does not change the deal value or the project. Update the project in Drum by hand in that case. Sending allow_additional_project: true would create a second project, which is almost never what you want for a revision.
Confirm with webhooks
Subscribe a Drum webhook to opportunity.won and project.created to confirm each conversion landed. One convert emits project.created (the new project), project.updated and opportunity.won (the opportunity); they can arrive in any order. The opportunity_id on the project payload matches the opportunity id from step 1. See Drum webhooks.
What the new project looks like
Number: the next project number from the project template (or from the location, when the template numbers by location; in that case the opportunity must have a location or the convert fails with
422 location_required).Name, description, team, and location: copied from the opportunity unless you send overrides.
Status: "Quote Accepted".
Deal value: the
budget_centsyou sent, shown on the opportunity.Task budget: zero. Drum builds a project's working budget from its tasks and budget lines, and a converted project has none until someone adds them in Drum.
budget_centsis recorded on the project but does not create tasks.Team members: the opportunity's assignees, with the account's first project role.
Limits
All API calls: 300 per minute per account.
Converts: 30 per minute per account.
The token expires on the date you set; a
401means it has expired or been deleted.
