Setup
Generate your signing secret
Configure your endpoint
Verifying the signature
doola sends aPOST with an X-Doola-Signature header: an HMAC SHA256 hex digest of the raw request body, keyed with your webhook secret. (HTTP header names are case-insensitive; many frameworks lowercase them to x-doola-signature on the way in.)
Payload
Every delivery is aPOST with the same envelope. Only eventPayload changes shape from event to event.
Events
document_* events for the same document, for example after doola re-issues a document. Handle uploads idempotently using documentId.form8821 signing milestones — completed, uploaded, and reminder — mirror the SS-4 ones and fire for whoever is asked to sign a Form 8821: a non-US founder who also requested an expedited EIN, where the signed form authorizes doola to retrieve the EIN letter from the IRS, or any founder doola has asked through a Form 8821 request. In each pair, signature_*_completed fires the instant the founder signs; document_*_uploaded fires once the signed PDF is stored and downloadable. signature_ss4_reset fires only when a non-US founder had already signed and a later name change voided that signature. signature_form8821_required is the one Form 8821 event that does not depend on residency at all: doola raises it when it could not obtain the EIN online. See Non-US founders for the full flow.company_ein_issued and document_einletter_uploaded both signal EIN issuance, at two distinct moments: company_ein_issued fires when doola records the EIN on the company (fetch the company to read the ein field), and document_einletter_uploaded fires once the IRS confirmation letter is stored and downloadable. They arrive independently, so do not assume an order. company_ein_issued fires only on the first issuance; a later correction to the EIN value does not re-fire it.company_name_options_required, signature_ss4_reset and signature_form8821_required announce a required action — something doola needs from you before that company can continue. They are the only events that block progress until you act. All three carry a requiredActionId: key your records on it and read the action against it. Only company_name_options_required is answered through the resolution endpoint; the two signature actions close themselves once the signature completes. An action you never received, because your endpoint was down, stays open and is readable from the open list.document_corporatebylaws_uploaded fires for CCorp companies only, and document_operatingagreement_uploaded fires for LLC companies only. doola generates the governance document shortly after the Articles of Organization are processed, so each event typically arrives soon after document_aoo_uploaded.Example payloads
A sample delivery for every event. WithineventPayload, only the fields relevant to that event are present; inapplicable fields are omitted entirely rather than sent as null, so parse defensively. eventPayload itself is null only for partner_webhook_disabled.
company_formation_submitted
company_formation_submitted
company_formation_completed
company_formation_completed
company_formation_failed
company_formation_failed
company_filing_date_updated
company_filing_date_updated
company_ein_issued
company_ein_issued
document_aoo_uploaded
document_aoo_uploaded
document_einletter_uploaded
document_einletter_uploaded
document_mail_uploaded
document_mail_uploaded
document_corporatebylaws_uploaded
document_corporatebylaws_uploaded
document_operatingagreement_uploaded
document_operatingagreement_uploaded
signature_ss4_completed
signature_ss4_completed
document_ss4_uploaded
document_ss4_uploaded
signature_ss4_reminder_due
signature_ss4_reminder_due
signature_form8821_completed
signature_form8821_completed
document_form8821_uploaded
document_form8821_uploaded
signature_form8821_reminder_due
signature_form8821_reminder_due
company_name_options_required
company_name_options_required
signature_ss4_reset
signature_ss4_reset
signature_form8821_required
signature_form8821_required
partner_webhook_disabled
partner_webhook_disabled
Payload fields
doolaCompanyId is on every company- and document-scoped payload. The rest appear only on the events noted below:
Delivery and retries
If your endpoint does not return a2xx, doola retries up to 5 times: at 1 minute, 15 minutes, 1 hour, 12 hours, and 24 hours after the previous attempt. Treat every delivery as at least once.
After all retries fail, doola automatically disables your endpoint and sends a final partner_webhook_disabled event. Fix your endpoint and re-enable it in the Partner Portal. Re-enabling is a deliberate partner action, so you confirm the endpoint is healthy before traffic resumes.
Every delivery attempt (timestamp, event, HTTP status, attempt number) is visible on the Partner Portal’s Events page, for the last 90 days.
eventId is stable across every retry of the same event, so dedupe on it and keep your handler idempotent.
Reconciliation
Webhooks are how you learn about a change quickly. They are not the only way to learn about it: every state a webhook announces is also readable from the API, so a missed delivery — your downtime, a disabled endpoint, a dropped retry — is always recoverable without contacting doola. Read the company:- Select the companies you believe are still in flight — anything whose Formation or EinCreation service is not yet
Completed. - Fetch each one and apply the table above, treating each field as the source of truth over your cached copy.
- Call
GET /v1/partner/required-actionsonce. Anything open there that you have no record of is blocking a formation and needs your input.
429 E_RATE_LIMITED long before it makes your data fresher — the events already tell you the moment something changes.