Inbound webhook secret
Generate or rotate the token a vendor uses to POST into an organization app
Inbound webhook secret
Two tenant routes tell an operator what to paste into a vendor portal. Both are mounted (repointegrations org-app store). Live merchant JWT against a real install: metadata 200, generate 200.
The write is a partial update of custom_params only. It cannot flip is_active. An earlier Go store treated zero fields as assignments and silently paused the install; that regression cannot be expressed here.
Quick reference
| Endpoint | Purpose |
|---|---|
GET /api/v1/org-apps/{orgAppId}/webhook-metadata | URL + accepted auth inputs. No secret value |
POST /api/v1/org-apps/{orgAppId}/webhook-secret | Create or reuse the token; return it once |
POST /api/v1/org-apps/{orgAppId}/webhook-secret?rotate=1 | Replace the stored token |
Requires a tenant Bearer token. A caller who can see the org but not this install gets 403 access denied to this organization app. A store miss is 404. A blank orgAppId (including /org-apps/%20/webhook-secret) is 400 orgAppId is required.
Metadata
GET /api/v1/org-apps/{orgAppId}/webhook-metadata{
"endpoint": {
"method_get": "GET",
"method_patch": "PATCH",
"method_post": "POST",
"path": "/api/webhooks/org-apps/{orgAppId}",
"public_origin": "https://linkit.works",
"url": "https://linkit.works/api/webhooks/org-apps/{orgAppId}"
},
"authentication": {
"accepted_inputs": [
"Authorization: Bearer <token>",
"Authorization: Basic base64(<token>:) — token as HTTP Basic username, empty password",
"Authorization: Basic base64(:<token>) — token as HTTP Basic password",
"X-Webhook-Token: <token>",
"?auth_token=<token>"
],
"accepted_tokens": [],
"notes": "custom_params.webhook_auth_token or organization_apps.api_secret is accepted…"
},
"post_payload_predicted": {},
"patch_payload_predicted": {}
}Orders installs also carry outbound_distribution and unified_payload_schema. Path families that are not …/org-apps/{id}:
| Slug family | Inbound path |
|---|---|
salla* | /api/webhooks/marketplace/salla — one global URL, merchant from the body |
shopify-* | /api/webhooks/shopify/{org_app_id} |
oto-shipping | /api/webhooks/org-apps/{org_app_id}/oto |
thechefz-orders | …/thechefz |
jahez-orders, jahez-shops-orders | …/jahez |
Go also sets X-Linkit-UI-Cache / ETag / 304. Reply has no header channel yet, so those headers are absent on v2.
Generate or rotate
POST /api/v1/org-apps/{orgAppId}/webhook-secretNo body. A body is ignored. The only extra input is ?rotate=.
rotate is truthy after trim + lower-case when it is exactly 1, true, yes, or on. Anything else — including omit — is false.
| State | Result |
|---|---|
No stored custom_params.webhook_auth_token (or it is whitespace) | Generate 32 random bytes as 64 hex chars. rotated: false |
Token already stored, rotate false | Reuse. Same token on the wire. rotated: false |
Token already stored, rotate true | Replace. rotated: true |
token_source is always "generated", including on the reuse path.
{
"organization_app_id": "oasys18d376386572a617",
"webhook_auth_token": "0123…64 hex chars",
"webhook_url": "https://linkit.works/api/webhooks/org-apps/oasys18d376386572a617",
"token_source": "generated",
"rotated": false
}Show the token once. The React App Store webhook step does: Generate / Show saved / Rotate. It does not generate on a fresh (not-yet-saved) install.
Entropy failure: 500 failed to generate webhook secret (cause not disclosed). A persist failure forwards the store message as 500.