Linkit

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

EndpointPurpose
GET /api/v1/org-apps/{orgAppId}/webhook-metadataURL + accepted auth inputs. No secret value
POST /api/v1/org-apps/{orgAppId}/webhook-secretCreate or reuse the token; return it once
POST /api/v1/org-apps/{orgAppId}/webhook-secret?rotate=1Replace 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 familyInbound 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-secret

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

StateResult
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 falseReuse. Same token on the wire. rotated: false
Token already stored, rotate trueReplace. 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.