[{"data":1,"prerenderedAt":25},["ShallowReactive",2],{"$fnq5ydh0ype7v":3},{"href":4,"title":5,"description":6,"kind":7,"mark":7,"planned":8,"contributors":9,"provenance":7,"html":10,"headings":11},"\u002Fdocs\u002Fapi\u002Fwebhooks","Webhooks","Start a run of a task, or answer a gate, from any system that can send an HTTP request.",null,false,[],"\u003Ch2 id=\"start-a-task\">Start a task\u003C\u002Fh2>\n\u003Cp>Every task has a webhook. \u003Ccode>POST\u003C\u002Fcode> the run's input as JSON, with your enterprise's webhook secret in a header:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl -X POST https:\u002F\u002Fapi.zerohuman.com\u002Fv1\u002Fwebhooks\u002F{enterprise}\u002Ftasks\u002F{task} \\\n  -H &quot;x-os-webhook-secret: $WEBHOOK_SECRET&quot; \\\n  -H &quot;content-type: application\u002Fjson&quot; \\\n  -d '{&quot;issue&quot;: 123}'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>{enterprise}\u003C\u002Fcode> is your enterprise's slug and \u003Ccode>{task}\u003C\u002Fcode> the task's. The task's \u003Cstrong>Triggers\u003C\u002Fstrong> panel in the portal shows\nits exact URL and a \u003Ccode>curl\u003C\u002Fcode> to copy, never the secret.\u003C\u002Fp>\n\u003Cp>The body is the run's input. If the task is already running when the call arrives, the new run waits until it can\nstart. A webhook starts the task the same way its schedule or a person does: the same version, the same gates, the\nsame spend limits.\u003C\u002Fp>\n\u003Ch2 id=\"answer-a-gate\">Answer a gate\u003C\u002Fh2>\n\u003Cp>A gate can be decided from outside the portal too:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl -X POST https:\u002F\u002Fapi.zerohuman.com\u002Fv1\u002Fwebhooks\u002F{enterprise}\u002Fgates\u002F{gateId} \\\n  -H &quot;x-os-webhook-secret: $WEBHOOK_SECRET&quot; \\\n  -H &quot;content-type: application\u002Fjson&quot; \\\n  -d '{&quot;decision&quot;: &quot;approve&quot;, &quot;note&quot;: &quot;Ship it.&quot;}'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>decision\u003C\u002Fcode> is \u003Ccode>approve\u003C\u002Fcode>, \u003Ccode>reject\u003C\u002Fcode> or \u003Ccode>request_changes\u003C\u002Fcode>, and \u003Ccode>note\u003C\u002Fcode> is optional. The decision is recorded exactly as\none made on \u003Cstrong>Gates\u003C\u002Fstrong> is, by the same rules: a gate already decided cannot be decided again. Whoever holds the webhook\nsecret can approve what goes live, so keep it as close as you would a signing key.\u003C\u002Fp>\n\u003Ch2 id=\"the-secret\">The secret\u003C\u002Fh2>\n\u003Cp>The secret is your enterprise's own. Every enterprise gets one when it is created, and it is stored only as a hash,\nso nobody can read it back, the portal included. \u003Cstrong>Settings → Webhooks\u003C\u002Fstrong> rotates it and shows the new secret\nexactly once; the previous one stops working at once. The secret an enterprise starts with is never shown, so using\nwebhooks starts with a rotation.\u003C\u002Fp>\n\u003Cp>A wrong secret and an unknown enterprise get the same \u003Ccode>401\u003C\u002Fcode>, so a call cannot tell you which enterprises exist.\u003C\u002Fp>\n\u003Ch2 id=\"history-and-replay\">History and replay\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Webhooks\u003C\u002Fstrong> in the portal lists every call your enterprise's webhooks received: what was sent (with credentials\nleft out and sensitive fields redacted), what the API answered, what happened next, and a link to the execution it\nstarted or continued. A call accepted means the webhook was consumed, not that its work has finished.\u003C\u002Fp>\n\u003Cp>A delivery can be \u003Cstrong>replayed\u003C\u002Fstrong>: the original request is applied again, through the task's or gate's current rules,\nas a new delivery linked to the original. Replaying a task starts a new run; replaying a gate decision continues its\nexecution, and a gate already decided refuses it. Calls that never authenticated, deliveries still in progress,\nand bodies that contain the webhook secret cannot be replayed.\u003C\u002Fp>\n\u003Cp>With an \u003Ca href=\"\u002Fdocs\u002Fapi\u002Fauthentication\">API token\u003C\u002Fa> scoped \u003Ccode>webhooks:read\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Call\u003C\u002Fth>\n\u003Cth>What it does\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv1\u002Fwebhooks\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Deliveries, paginated, with search, sorting, and \u003Ccode>status\u003C\u002Fcode> and \u003Ccode>kind\u003C\u002Fcode> filters.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv1\u002Fwebhooks\u002F{id}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>One delivery: its request, response and what followed.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>POST \u002Fv1\u002Fwebhooks\u002F{id}\u002Freplay\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Replay it (\u003Ccode>webhooks:write\u003C\u002Fcode>). Send \u003Ccode>{ &quot;idempotencyKey&quot;: &quot;&lt;uuid&gt;&quot; }\u003C\u002Fcode>: the same key returns the same replay rather than dispatching twice.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n",[12,16,19,22],{"id":13,"text":14,"level":15,"planned":8},"start-a-task","Start a task",2,{"id":17,"text":18,"level":15,"planned":8},"answer-a-gate","Answer a gate",{"id":20,"text":21,"level":15,"planned":8},"the-secret","The secret",{"id":23,"text":24,"level":15,"planned":8},"history-and-replay","History and replay",1791124519345]