Skip to main content

How to convert an accepted Quotient quote into a Drum project

Use a Quotient quote_accepted event to find an opportunity, choose a project status and create one Drum delivery project safely.

Written by Ben Walker

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

  1. Create an integration user in Drum with its own role that holds only:

    • api_read

    • api_create

    • read_all_projects

    • update_all_opportunities

    • create_projects

    • view_opportunity_financial_values (needed to send budget_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.

  2. 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.

  3. 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.00 becomes 4850000. It is stored on the project and becomes the opportunity's deal value.

  • expected_project_status_id (optional): the project_status.id from the step 1 result. If someone moved the opportunity between step 1 and step 3, Drum refuses with 409 stale_state rather than converting a record that changed under you.

Read the response

Response

Meaning

Action

201, created: true

The project was created and the opportunity is won

Done

200, created: false

A project already exists for this opportunity

Done. Nothing changed

409 stale_state

The opportunity status changed since step 1

Stop and notify a person

409 retry_later

Another request holds the opportunity

Retry with backoff

409 rate_limited or 429

More than 30 converts in a minute

Retry after a minute

5xx

Drum error

Retry with backoff

403 financials_not_permitted

The token's role lacks view_opportunity_financial_values

Fix the role, then rerun

404

The opportunity id is wrong or hidden from the token user

Stop and notify a person

Any other 422

The opportunity cannot be converted (for example no company client, or linked to a variation); the code says why

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_cents you 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_cents is 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 401 means it has expired or been deleted.

Did this answer your question?