On this page

API

Webhooks operations

Signed event delivery to your servers.

Signed event delivery to your servers. Paths are relative to https://reuseforge.com/api/v1.

Operations in this area
OperationMethodPath
List webhooksGET/webhooks
Create a webhookPOST/webhooks
Get a webhookGET/webhooks/{webhook_id}
Update a webhookPATCH/webhooks/{webhook_id}
Delete a webhookDELETE/webhooks/{webhook_id}
Rotate the signing secretPOST/webhooks/{webhook_id}/rotate-secret
Send a test pingPOST/webhooks/{webhook_id}/test
List deliveriesGET/webhooks/{webhook_id}/deliveries
Redeliver an eventPOST/webhooks/{webhook_id}/deliveries/{delivery_id}/redeliver

List webhooks

GET /webhooks Enabled on reuseforge.com

Webhook endpoints of the authenticated account (and of organizations you administer when account is given).

List webhooks: facts
PropertyValue
Operation IDlist_webhooks
AuthenticationBearer token holding webhooks:manage
Rate tierread: 60/min per IP anonymous, 600/min per token with a token
Python SDKclient.list_webhooks(...)
JavaScript SDKclient.listWebhooks(...)
CLIrf webhooks list
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

List webhooks: parameters
NameInTypeRequiredDescription
cursorquerystringnoOpaque cursor from the previous page's next_cursor.
limitqueryintegernoPage size. Default 30.

Responses

List webhooks: responses
StatusMeaningBody
200 OKA page of webhooks. Secrets are never listed.application/json: WebhookPage
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited

Example

curl

bash
curl 'https://reuseforge.com/api/v1/webhooks' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

for entry in client.list_webhooks():  # iterating fetches further pages on demand
    print(entry["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

for await (const entry of client.listWebhooks()) {  // iterating fetches further pages on demand
  console.log(entry.id);
}

CLI

bash
rf webhooks list

# rf webhooks list [options]
# all options: rf webhooks list --help

Response 200 OK:

json
{
  "data": [
    {
      "id": "whk_ordersandpub",
      "object": "webhook",
      "url": "https://hooks.acme.example/reuseforge",
      "description": "Production order and publish events",
      "events": [
        "item.published",
        "item.version.published",
        "order.created",
        "order.funded",
        "order.released"
      ],
      "account": "acme",
      "status": "enabled",
      "disabled_reason": null,
      "api_version": "1",
      "consecutive_failures": 0,
      "last_delivery_at": "2026-11-03T10:08:31Z",
      "last_success_at": "2026-11-03T10:08:31Z",
      "created_at": "2026-10-01T12:00:00Z",
      "updated_at": "2026-10-01T12:00:00Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Create a webhook

POST /webhooks Enabled on reuseforge.com

Registers an HTTPS endpoint. The signing secret (secret, whsec_...) is returned once; store it. The URL must be HTTPS on a public host (no IP literals, no private or link-local ranges, no credentials in the URL, port 443 or 8443 only; plain http://localhost is accepted only by self-hosted nodes). Redirects are not followed. At most 20 endpoints per account and one endpoint per URL (409 already_exists). The platform sends a ping event right after creation.

Receiving an event is reading the resource in it, so the credential also needs the read scope of every subscribed type: orders:read for order.* and payout.sent, items:read for item.*, review.created and verification.completed, projects:read for project.*. * needs all three. Without them: 403 insufficient_scope.

Create a webhook: facts
PropertyValue
Operation IDcreate_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
IdempotencyIdempotency-Key header, optional. The SDKs and the CLI send one for you.
Python SDKclient.create_webhook(...)
JavaScript SDKclient.createWebhook(...)
CLIrf webhooks create
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Create a webhook: parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringnoClient-chosen unique key (1 to 255 printable ASCII characters, a UUID is ideal). A repeat of the same request with the same key within 24 hours returns the first response with Idempotent-Replayed: true. The same key with a different body returns 422 idempotency_key_reuse; a repeat while the first call is still running returns 409 idempotency_in_progress.

Request body

application/json, required, schema WebhookCreate

Create a webhook: request fields
FieldTypeRequiredDescription
urlstring (uri)yes
descriptionstringno
eventsarray of EventType or string: *yes
accountstringnoOrganization handle you administer. Defaults to you.

Responses

Create a webhook: responses
StatusMeaningBody
201 CreatedThe webhook with its one-time secret.application/json: WebhookWithSecret
400The request is malformed (bad JSON, unknown or mistyped parameter, invalid cursor).Problem. Codes: invalid_request, invalid_json, invalid_parameter, invalid_cursor, idempotency_key_required
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
409The request conflicts with current state (duplicate resource, wrong lifecycle state, idempotency conflict).Problem. Codes: conflict, already_exists, invalid_state, idempotency_in_progress
422The body is well-formed JSON but invalid (validation_failed with per-field errors), or a business rule rejects it (payment_invalid, webhook_url_forbidden, idempotency_key_reuse).Problem. Codes: validation_failed, payment_invalid, rail_unsupported, idempotency_key_reuse, webhook_url_forbidden, invalid_signature, integrity_mismatch
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited
503Temporarily unable to serve (maintenance or a dependency is down). Honour Retry-After.Problem. Codes: unavailable

Example

curl

bash
curl -X POST 'https://reuseforge.com/api/v1/webhooks' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://hooks.acme.example/reuseforge",
  "description": "Production order and publish events",
  "events": [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released"
  ],
  "account": "acme"
}'

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.create_webhook(
    url="https://hooks.acme.example/reuseforge",
    description="Production order and publish events",
    events=[
            "item.published",
            "item.version.published",
            "order.created",
            "order.funded",
            "order.released",
        ],
    account="acme",
)
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.createWebhook({
  url: "https://hooks.acme.example/reuseforge",
  description: "Production order and publish events",
  events: [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released",
  ],
  account: "acme",
});
console.log(result.id);

CLI

bash
rf webhooks create --url https://hooks.acme.example/reuseforge --description 'Production order and publish events' --events item.published,item.version.published,order.created,order.funded,order.released --account acme

# rf webhooks create [options]
# all options: rf webhooks create --help

Response 201 Created:

json
{
  "id": "whk_ordersandpub",
  "object": "webhook",
  "url": "https://hooks.acme.example/reuseforge",
  "description": "Production order and publish events",
  "events": [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released"
  ],
  "account": "acme",
  "status": "enabled",
  "disabled_reason": null,
  "api_version": "1",
  "consecutive_failures": 0,
  "last_delivery_at": null,
  "last_success_at": null,
  "created_at": "2026-10-01T12:00:00Z",
  "updated_at": "2026-10-01T12:00:00Z",
  "secret": "whsec_kq7x3n2m5v4b6c8d9f2g3h4j5k6m7n8p"
}

Get a webhook

GET /webhooks/{webhook_id} Enabled on reuseforge.com

One endpoint with its delivery health.

Get a webhook: facts
PropertyValue
Operation IDget_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierread: 60/min per IP anonymous, 600/min per token with a token
Python SDKclient.get_webhook(...)
JavaScript SDKclient.getWebhook(...)
CLIrf webhooks get
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Get a webhook: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes

Responses

Get a webhook: responses
StatusMeaningBody
200 OKThe webhook.application/json: Webhook
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited

Example

curl

bash
curl 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.get_webhook("whk_p8d3f6j1s5a2")
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.getWebhook("whk_p8d3f6j1s5a2");
console.log(result.id);

CLI

bash
rf webhooks get whk_p8d3f6j1s5a2

# rf webhooks get <webhook_id>
# all options: rf webhooks get --help

Response 200 OK:

json
{
  "id": "whk_ordersandpub",
  "object": "webhook",
  "url": "https://hooks.acme.example/reuseforge",
  "description": "Production order and publish events",
  "events": [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released"
  ],
  "account": "acme",
  "status": "enabled",
  "disabled_reason": null,
  "api_version": "1",
  "consecutive_failures": 0,
  "last_delivery_at": "2026-11-03T10:08:31Z",
  "last_success_at": "2026-11-03T10:08:31Z",
  "created_at": "2026-10-01T12:00:00Z",
  "updated_at": "2026-10-01T12:00:00Z"
}

Update a webhook

PATCH /webhooks/{webhook_id} Enabled on reuseforge.com

Change the URL, events or description, or set status to enabled to re-enable an endpoint that was automatically disabled (the failure counter resets). Adding event types, and pointing an endpoint at another URL, need the read scope of the types it receives (see create_webhook); renaming, narrowing and disabling need webhooks:manage only. A URL another endpoint of the account already uses is 409 already_exists.

Update a webhook: facts
PropertyValue
Operation IDupdate_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
Python SDKclient.update_webhook(...)
JavaScript SDKclient.updateWebhook(...)
CLIrf webhooks update
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Update a webhook: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes

Request body

application/json, required, schema WebhookUpdate

Update a webhook: request fields
FieldTypeRequiredDescription
urlstring (uri)no
descriptionstringno
eventsarray of EventType or string: *no
statusstring: enabled, disabledno

Responses

Update a webhook: responses
StatusMeaningBody
200 OKThe updated webhook.application/json: Webhook
400The request is malformed (bad JSON, unknown or mistyped parameter, invalid cursor).Problem. Codes: invalid_request, invalid_json, invalid_parameter, invalid_cursor, idempotency_key_required
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
409The request conflicts with current state (duplicate resource, wrong lifecycle state, idempotency conflict).Problem. Codes: conflict, already_exists, invalid_state, idempotency_in_progress
422The body is well-formed JSON but invalid (validation_failed with per-field errors), or a business rule rejects it (payment_invalid, webhook_url_forbidden, idempotency_key_reuse).Problem. Codes: validation_failed, payment_invalid, rail_unsupported, idempotency_key_reuse, webhook_url_forbidden, invalid_signature, integrity_mismatch
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited

Example

curl

bash
curl -X PATCH 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "enabled"
}'

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.update_webhook("whk_p8d3f6j1s5a2", status="enabled")
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.updateWebhook("whk_p8d3f6j1s5a2", { status: "enabled" });
console.log(result.id);

CLI

bash
rf webhooks update whk_p8d3f6j1s5a2 --status enabled

# rf webhooks update <webhook_id> [options]
# all options: rf webhooks update --help

Response 200 OK:

json
{
  "id": "whk_ordersandpub",
  "object": "webhook",
  "url": "https://hooks.acme.example/reuseforge",
  "description": "Production order and publish events",
  "events": [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released"
  ],
  "account": "acme",
  "status": "enabled",
  "disabled_reason": null,
  "api_version": "1",
  "consecutive_failures": 0,
  "last_delivery_at": "2026-11-03T10:08:31Z",
  "last_success_at": "2026-11-03T10:08:31Z",
  "created_at": "2026-10-01T12:00:00Z",
  "updated_at": "2026-10-01T12:00:00Z"
}

Delete a webhook

DELETE /webhooks/{webhook_id} Enabled on reuseforge.com

Stops all future deliveries and drops pending retries. Idempotent.

Delete a webhook: facts
PropertyValue
Operation IDdelete_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
Python SDKclient.delete_webhook(...)
JavaScript SDKclient.deleteWebhook(...)
CLIrf webhooks delete
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Delete a webhook: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes

Responses

Delete a webhook: responses
StatusMeaningBody
204 No ContentDeleted.no body
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited

Example

curl

bash
curl -X DELETE 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

client.delete_webhook("whk_p8d3f6j1s5a2")

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

await client.deleteWebhook("whk_p8d3f6j1s5a2");

CLI

bash
rf webhooks delete whk_p8d3f6j1s5a2

# rf webhooks delete <webhook_id>
# all options: rf webhooks delete --help

Response 204 No Content with an empty body.

Rotate the signing secret

POST /webhooks/{webhook_id}/rotate-secret Enabled on reuseforge.com

Issues a new secret. For 24 hours every delivery carries two v1 signatures (new first, old second) so receivers can switch without downtime; after that only the new secret signs.

Rotate the signing secret: facts
PropertyValue
Operation IDrotate_webhook_secret
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
IdempotencyIdempotency-Key header, optional. The SDKs and the CLI send one for you.
Python SDKclient.rotate_webhook_secret(...)
JavaScript SDKclient.rotateWebhookSecret(...)
CLIrf webhooks rotate-secret
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Rotate the signing secret: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes
Idempotency-KeyheaderstringnoClient-chosen unique key (1 to 255 printable ASCII characters, a UUID is ideal). A repeat of the same request with the same key within 24 hours returns the first response with Idempotent-Replayed: true. The same key with a different body returns 422 idempotency_key_reuse; a repeat while the first call is still running returns 409 idempotency_in_progress.

Responses

Rotate the signing secret: responses
StatusMeaningBody
200 OKThe webhook with the new one-time secret.application/json: WebhookWithSecret
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited
503Temporarily unable to serve (maintenance or a dependency is down). Honour Retry-After.Problem. Codes: unavailable

Example

curl

bash
curl -X POST 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2/rotate-secret' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.rotate_webhook_secret("whk_p8d3f6j1s5a2")
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.rotateWebhookSecret("whk_p8d3f6j1s5a2");
console.log(result.id);

CLI

bash
rf webhooks rotate-secret whk_p8d3f6j1s5a2

# rf webhooks rotate-secret <webhook_id>
# all options: rf webhooks rotate-secret --help

Response 200 OK:

json
{
  "id": "whk_ordersandpub",
  "object": "webhook",
  "url": "https://hooks.acme.example/reuseforge",
  "description": "Production order and publish events",
  "events": [
    "item.published",
    "item.version.published",
    "order.created",
    "order.funded",
    "order.released"
  ],
  "account": "acme",
  "status": "enabled",
  "disabled_reason": null,
  "api_version": "1",
  "consecutive_failures": 0,
  "last_delivery_at": "2026-11-03T10:08:31Z",
  "last_success_at": "2026-11-03T10:08:31Z",
  "created_at": "2026-10-01T12:00:00Z",
  "updated_at": "2026-11-03T10:30:00Z",
  "secret": "whsec_w4x9c2v7b1n6m3q8r5t0y2u4i6o8p1as",
  "previous_secret_expires_at": "2026-11-04T10:30:00Z"
}

Send a test ping

POST /webhooks/{webhook_id}/test Enabled on reuseforge.com

Synchronously delivers a signed ping event and returns the delivery result (success or the failure you would see in production). Does not count toward auto-disable.

Send a test ping: facts
PropertyValue
Operation IDtest_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
Python SDKclient.test_webhook(...)
JavaScript SDKclient.testWebhook(...)
CLIrf webhooks test
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Send a test ping: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes

Responses

Send a test ping: responses
StatusMeaningBody
200 OKThe delivery attempt.application/json: WebhookDelivery
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited
503Temporarily unable to serve (maintenance or a dependency is down). Honour Retry-After.Problem. Codes: unavailable

Example

curl

bash
curl -X POST 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2/test' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.test_webhook("whk_p8d3f6j1s5a2")
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.testWebhook("whk_p8d3f6j1s5a2");
console.log(result.id);

CLI

bash
rf webhooks test whk_p8d3f6j1s5a2

# rf webhooks test <webhook_id>
# all options: rf webhooks test --help

Response 200 OK:

json
{
  "id": "whd_pingdelivery2",
  "object": "webhook_delivery",
  "webhook_id": "whk_ordersandpub",
  "event_id": "evt_pingevent222",
  "event_type": "ping",
  "attempt": 1,
  "state": "succeeded",
  "scheduled_at": "2026-11-03T10:31:00Z",
  "delivered_at": "2026-11-03T10:31:00Z",
  "response_status": 200,
  "response_ms": 96,
  "response_excerpt": "pong",
  "error": null,
  "next_attempt_at": null
}

List deliveries

GET /webhooks/{webhook_id}/deliveries Enabled on reuseforge.com

Delivery attempts for the last 30 days, newest first, with the response status and an excerpt of the receiver's reply.

List deliveries: facts
PropertyValue
Operation IDlist_webhook_deliveries
AuthenticationBearer token holding webhooks:manage
Rate tierread: 60/min per IP anonymous, 600/min per token with a token
Python SDKclient.list_webhook_deliveries(...)
JavaScript SDKclient.listWebhookDeliveries(...)
CLIrf webhooks deliveries
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

List deliveries: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes
statequerystring: pending, retrying, succeeded, failed, exhaustedno
event_typequeryEventTypeno
cursorquerystringnoOpaque cursor from the previous page's next_cursor.
limitqueryintegernoPage size. Default 30.

Responses

List deliveries: responses
StatusMeaningBody
200 OKA page of deliveries.application/json: WebhookDeliveryPage
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited

Example

curl

bash
curl 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2/deliveries' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

for entry in client.list_webhook_deliveries("whk_p8d3f6j1s5a2"):  # iterating fetches further pages on demand
    print(entry["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

for await (const entry of client.listWebhookDeliveries("whk_p8d3f6j1s5a2")) {  // iterating fetches further pages on demand
  console.log(entry.id);
}

CLI

bash
rf webhooks deliveries whk_p8d3f6j1s5a2

# rf webhooks deliveries <webhook_id> [options]
# all options: rf webhooks deliveries --help

Response 200 OK:

json
{
  "data": [
    {
      "id": "whd_deliveryok22",
      "object": "webhook_delivery",
      "webhook_id": "whk_ordersandpub",
      "event_id": "evt_orderfunded2",
      "event_type": "order.funded",
      "attempt": 1,
      "state": "succeeded",
      "scheduled_at": "2026-11-03T10:07:12Z",
      "delivered_at": "2026-11-03T10:07:13Z",
      "response_status": 200,
      "response_ms": 184,
      "response_excerpt": "ok",
      "error": null,
      "next_attempt_at": null
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Redeliver an event

POST /webhooks/{webhook_id}/deliveries/{delivery_id}/redeliver Enabled on reuseforge.com

Re-sends the same event (same evt_ id, fresh signature timestamp) as a new delivery attempt. Receivers must treat the event id as the idempotency key. The credential needs the read scope of the event's type (see create_webhook); pings need none and count toward the per-minute ping limit of test_webhook. 409 invalid_state while the delivery is still being attempted or the endpoint is disabled, 410 gone once the event is older than 30 days.

Redeliver an event: facts
PropertyValue
Operation IDredeliver_webhook
AuthenticationBearer token holding webhooks:manage
Rate tierwrite: not allowed anonymous, 120/min per token with a token
IdempotencyIdempotency-Key header, optional. The SDKs and the CLI send one for you.
Python SDKclient.redeliver_webhook(...)
JavaScript SDKclient.redeliverWebhook(...)
CLIrf webhooks redeliver
MCP toolnot exposed as a tool
Deploymentsreuseforge.com: enabled. Python node: not implemented (answers 501).

Parameters

Redeliver an event: parameters
NameInTypeRequiredDescription
webhook_idpathstringyes
delivery_idpathstringyes
Idempotency-KeyheaderstringnoClient-chosen unique key (1 to 255 printable ASCII characters, a UUID is ideal). A repeat of the same request with the same key within 24 hours returns the first response with Idempotent-Replayed: true. The same key with a different body returns 422 idempotency_key_reuse; a repeat while the first call is still running returns 409 idempotency_in_progress.

Responses

Redeliver an event: responses
StatusMeaningBody
202 AcceptedScheduled.application/json: WebhookDelivery
401Missing, malformed, expired or revoked credentials.Problem. Codes: unauthorized, invalid_token, token_expired
403Authenticated, but not allowed. Most often a missing scope (insufficient_scope, with required_scopes), an exceeded spend limit, or a role on the owning account that is too low. Also version_quarantined (the security scan or a moderator blocked the version you asked for) and review_removed (a moderator removed your review).Problem. Codes: insufficient_scope, forbidden, account_suspended, email_unverified, spend_limit_exceeded, purchase_required, quota_exceeded, version_quarantined, review_removed
404No such resource, or it is private and the caller may not know it exists.Problem. Codes: not_found
409The request conflicts with current state (duplicate resource, wrong lifecycle state, idempotency conflict).Problem. Codes: conflict, already_exists, invalid_state, idempotency_in_progress
410The resource existed and is permanently unavailable (retracted item, expired plan).Problem. Codes: gone, plan_expired
429Rate limit for the operation's tier exceeded. Wait Retry-After seconds.Problem. Codes: rate_limited
503Temporarily unable to serve (maintenance or a dependency is down). Honour Retry-After.Problem. Codes: unavailable

Example

curl

bash
curl -X POST 'https://reuseforge.com/api/v1/webhooks/whk_p8d3f6j1s5a2/deliveries/whd_r2v7c4x9n6e1/redeliver' \
  -H "Authorization: Bearer $REUSEFORGE_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

Python

python
import reuseforge

client = reuseforge.Client()  # token from REUSEFORGE_TOKEN, or the file `rf login` wrote

result = client.redeliver_webhook("whk_p8d3f6j1s5a2", "whd_r2v7c4x9n6e1")
print(result["id"])

JavaScript

javascript
import { ReuseForge } from '@reuseforge/sdk';

const client = new ReuseForge({ token: process.env.REUSEFORGE_TOKEN });

const result = await client.redeliverWebhook("whk_p8d3f6j1s5a2", "whd_r2v7c4x9n6e1");
console.log(result.id);

CLI

bash
rf webhooks redeliver whk_p8d3f6j1s5a2 whd_r2v7c4x9n6e1

# rf webhooks redeliver <webhook_id> <delivery_id>
# all options: rf webhooks redeliver --help

Response 202 Accepted:

json
{
  "id": "whd_redelivery222",
  "object": "webhook_delivery",
  "webhook_id": "whk_ordersandpub",
  "event_id": "evt_orderfunded2",
  "event_type": "order.funded",
  "attempt": 2,
  "state": "pending",
  "scheduled_at": "2026-11-03T10:40:00Z",
  "delivered_at": null,
  "response_status": null,
  "response_ms": null,
  "response_excerpt": null,
  "error": null,
  "next_attempt_at": "2026-11-03T10:40:00Z"
}