Skip to content

Quickstart

Creating a submission starts the run. There is no separate “go shop it” step: as soon as the create commits, Hedge extracts the risk, matches appetite, emails the producer the clearance listing every market being tried, opens the lanes, and quotes the instant-quote markets. Everything below reads that run back or acts on it. The fastest path is the hedge CLI; the same steps in curl follow.

  1. Install and sign in.

    Terminal window
    npm i -g hedge-broker
    hedge login

    hedge login uses the OAuth 2.1 device flow: it prints a short code and a URL, you approve the sign-in in the broker portal, and the CLI stores a short-lived token. For a script, sign in with an API key from Settings → API keys instead: hedge login --client-id bac_... --client-secret bas_... (or set HEDGE_CLIENT_SECRET). Homebrew and a one-line installer are also available; see the CLI guide.

  2. Send the risk.

    Terminal window
    hedge intake ./acord-125.pdf ./loss-runs.pdf \
    --text "Acme Roofing LLC, residential roofing contractor in San Jose CA, 12 employees, no prior losses. GL and property, effective 2026-10-01." \
    --producer-email dana@youragency.com

    Hedge reads the insured, contact, address and NAICS out of the text, stores the PDFs on the new submission, extracts them in the background, and starts the run. The response carries the submission_id, marketing_status: matching and the next call to make. Add --hold to keep the draft and release it later with hedge finalize <id>.

  3. Read the markets.

    Terminal window
    hedge markets <submission-id> --wait

    Matching usually lands within about five minutes (--wait polls). The result is always the three categories, in order:

    • Hedge Instant Quote (instant_quote): connected carrier APIs, quoted on recorded favorable assumptions. Each assumption is listed on the lane with [ ] while it still stands and [x] once confirmed.
    • Hedge Binding (binding): markets Hedge quotes for you.
    • Hedge Specialty (specialty): email markets that need the completed ACORDs, program requirements and loss runs.

    Each lane shows its status, needs_from_you (only while it is gapped) and released quotes with their quote_id.

  4. Read the thread and answer.

    Terminal window
    hedge thread <submission-id>
    hedge reply <submission-id> "Payroll is 900k. No hot-tar work, nothing over 3 stories."
    hedge answer-asks <submission-id> # list the outstanding asks and keys
    hedge answer-asks <submission-id> --set years_in_business=8 --set prior_losses=false
    hedge upload <submission-id> ./supplement.pdf

    The thread is the same conversation the producer has by email: the clearance email, Hedge’s questions, market-plan updates and quote deliveries, oldest first. hedge reply is identical in effect to replying to that email; Hedge answers on the thread within a couple of minutes.

  5. Bind, with attestation.

    Terminal window
    hedge bind <submission-id> --quote <quote-id> --payment in_full

    While any assumption behind the quote stands unconfirmed, the API answers 409 assumptions_unconfirmed and the CLI prints each statement with the exact re-run. Once the retail agent has reviewed them:

    Terminal window
    hedge bind <submission-id> --quote <quote-id> --payment in_full --attest
    hedge bind-upload <submission-id> <bind-request-id> <contingency-id> ./signed-app.pdf
    hedge bind-submit <submission-id> <bind-request-id>
    hedge bind-status <submission-id> <bind-request-id>

    bind drafts the request (nothing goes to the carrier yet), bind-upload satisfies the carrier’s pre-bind contingencies, bind-submit sends it to Hedge for placement. A bound event follows on the events feed and your webhooks, and the policy appears under hedge policies.

Every CLI command maps to a REST endpoint under https://api.hedgespecialty.com/api/v1. Requests carry a short-lived OAuth 2.1 bearer token in the Authorization header; see Authentication for the device flow or the client_credentials exchange of an API key. Writes need the broker_submit scope, and a machine credential must name the producing broker with producer_email on every write.

POST /broker/intake is multipart: text and/or files (up to 20 PDFs, 15 MB each), plus optional insured_name, effective_date, lines_of_business, primary_state, producer_email and hold. Either text or insured_name is required.

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/broker/intake" \
-H "Authorization: Bearer $HEDGE_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-F 'text=Acme Roofing LLC, residential roofing contractor in San Jose CA, 12 employees, no prior losses. GL and property, effective 2026-10-01.' \
-F 'files=@acord-125.pdf;type=application/pdf' \
-F 'files=@loss-runs.pdf;type=application/pdf' \
-F 'producer_email=dana@youragency.com'

The 201 body is an IntakeCreated: submission_id, marketing_status (matching, or awaiting_finalization when held), next_step, the stored documents, the applicant Hedge recorded, any warnings, and the portal_url. Prefer structured JSON? POST /broker/submissions takes the applicant, lines of business and narrative as before and now starts the run too; "hold": true defers it until POST .../finalize.

Terminal window
curl "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/markets" \
-H "Authorization: Bearer $HEDGE_TOKEN"
{
"submission_id": "…",
"generated_at": "2026-09-19T16:02:11Z",
"categories": [
{
"category": "instant_quote",
"label": "Hedge Instant Quote",
"description": "Connected carrier APIs, quoted on recorded favorable assumptions.",
"lanes": [
{
"lane_id": "…", "market_name": "Coterie", "program": "BOP", "lines": ["commercial_general_liability"],
"status": "quoted", "status_label": "Quoted", "submit_ready": true, "bound": false,
"assumptions": [
{ "key": "years_in_business", "label": "In business 3+ years", "value": 3, "confirmed": false }
],
"quotes": [ { "quote_id": "…", "premium_cents": 855900, "premium": "$8,559", "lines": ["commercial_general_liability"] } ]
}
]
},
{ "category": "binding", "label": "Hedge Binding", "description": "…", "lanes": [ { "…": "…", "needs_from_you": ["Signed ACORD 125", "5-year loss runs"] } ] },
{ "category": "specialty", "label": "Hedge Specialty", "description": "…", "lanes": [] }
]
}

All three categories are always present, in that order, even when empty. An empty view while marketing_status is matching is not “no appetite”; poll again in a minute or two.

Terminal window
curl "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/thread?limit=50" \
-H "Authorization: Bearer $HEDGE_TOKEN"

Messages come oldest first as ThreadMessage objects (direction is relative to Hedge: outbound is Hedge writing to you, inbound is your brokerage). A non-null next_cursor means more may exist: store it and call again with since=<cursor> until you receive null. Reply exactly as you would reply to the email:

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/thread" \
-H "Authorization: Bearer $HEDGE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"body": "Payroll is 900k. No hot-tar work, nothing over 3 stories.",
"producer_email": "dana@youragency.com"
}'

202 returns the message_id; Hedge’s answer arrives on the thread and on the submission.message webhook. Typed asks the matched markets still need can also be answered in one batch: read GET .../outstanding-requirements and post { "answers": [ { "key": "…", "value": … } ] } to .../outstanding-requirements/answers.

Webhook endpoints are managed in the broker portal under Settings → Webhooks (brokerage admins only; the management API is portal-session-only by design, so a leaked machine key can never redirect your event stream). Give it an HTTPS URL and, optionally, an event_types filter: any feed event type (market_attached, quote_received, status_changed, declined, withdrawn, blocked, bound) plus message for thread messages. No filter means everything. Hedge then POSTs:

  • submission.events: new submission events, the same objects as GET .../events.
  • submission.message: one new ThreadMessage, the same object as GET .../thread.

Acknowledge with any 2xx within 10 seconds. Deliveries are signed (svix-compatible) and retried; dedupe on svix-id. See the Webhooks tag in the API Reference.

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/bind-requests" \
-H "Authorization: Bearer $HEDGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "quote_id": "'"$QUOTE_ID"'", "payment_option": "in_full", "producer_email": "dana@youragency.com" }'

While assumptions behind the quote stand unconfirmed, the response is 409:

{
"detail": {
"code": "assumptions_unconfirmed",
"message": "…",
"bind_request_id": "…",
"assumptions": [ { "key": "years_in_business", "label": "In business 3+ years", "value": 3 } ]
}
}

The draft is kept. Show the retail agent each statement; once they confirm, re-POST with "attest_assumptions": true (or the list of confirmed keys) to receive the 201 BindRequestRead. Then satisfy each pre-bind contingency by posting a PDF to its upload_path, and submit:

Terminal window
curl -X POST "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/bind-requests/$BIND_REQUEST_ID/contingencies/$CONTINGENCY_ID/document" \
-H "Authorization: Bearer $HEDGE_TOKEN" \
-F 'file=@signed-app.pdf;type=application/pdf' \
-F 'producer_email=dana@youragency.com'
curl -X POST "https://api.hedgespecialty.com/api/v1/broker/submissions/$SUBMISSION_ID/bind-requests/$BIND_REQUEST_ID/submit" \
-H "Authorization: Bearer $HEDGE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "producer_email": "dana@youragency.com" }'

Track it with GET .../bind-requests/{bind_request_id}; a bound event follows and the policy appears under GET /broker/policies.

The device flow for people, client_credentials for servers, and how producer_email attributes machine writes. See Authentication.