Events API, interactions, admin settings, and the profile Connect Slack route.
Auth summary
| Access | Routes |
|---|---|
manage_options | GET/POST /wp-json/prc-slack/v1/settings |
Logged-in self, or edit_users | POST /wp-json/prc-slack/v1/connect-user |
Slack signing secret and chat enabled (Connection::authenticate()) | /events and its one-release proxies |
Slack signing secret and workspace ID (Connection::verify_signed_request()) | /interactions and its one-release proxies |
| Cursor Origin Ed25519 signature | /origin/webhooks |
Settings
| Method | Path | Permission |
|---|---|---|
GET | /wp-json/prc-slack/v1/settings | manage_options |
POST | /wp-json/prc-slack/v1/settings | manage_options |
GET redacts stored token and signing-secret overrides as ********. POST with that sentinel keeps the stored secret. GET also returns the read-only factory_webhook_url, origin_api_configured, and environment values. POST rejects invalid payloads with HTTP 400 and { "error": "Invalid payload." }.
Connect user
| Method | Path | Permission |
|---|---|---|
POST | /wp-json/prc-slack/v1/connect-user | Cookie/nonce. Self or edit_users |
Looks up the profile user's WordPress email with Slack users.lookupByEmail and writes prc_slack_user_id. It does not return an existing meta value first, so Reconnect Slack can replace a stale ID. Omit user_id to connect the current user. Admins editing someone else must send that user's ID.
A miss returns HTTP 404 and names the email. If the bot token lacks users:read.email, the route returns HTTP 503 and asks you to reinstall or re-auth the Slack app. The WordPress profile Connect Slack button calls this route and hides when prc-slack cannot send.
/wp-json/prc-slack/v1/connect-user
Content-Type application/json{
"user_id": 12
}
{
"slack_user_id": "U01ABCD2EFG",
"email": "ada@example.com"
}Slack webhooks
| Method | Path | Notes |
|---|---|---|
POST | /wp-json/prc-slack/v1/events | Canonical Events API. URL verification returns { "challenge": "…" }. |
POST | /wp-json/prc-slack/v1/interactions | Canonical interactivity ACK |
POST | /wp-json/prc-agents-trending-news/v2/slack/events | One-release proxy; Deprecation: true |
POST | /wp-json/prc-agents-trending-news/v2/slack/interactions | One-release proxy; Deprecation: true |
POST | /wp-json/prc-api/v3/nexus/slack/trending-news | Legacy proxy; Deprecation: true |
POST | /wp-json/prc-api/v3/nexus/slack/interactive | Legacy proxy; Deprecation: true |
/wp-json/prc-slack/v1/events
Content-Type application/jsonX-Slack-Signature v0=…X-Slack-Request-Timestamp 1710000000{
"type": "url_verification",
"challenge": "example-challenge"
}
{
"challenge": "example-challenge"
}/interactions verifies the Slack HMAC, replay window, and team ID without reading the PRC Nexus chat toggle. It routes block_actions with action ID prc_factory_merge to the factory handler. Other actions receive the same { "ok": true } response and no factory work.
Origin webhooks
| Method | Path | Permission |
|---|---|---|
POST | /wp-json/prc-slack/v1/origin/webhooks | Cursor Origin Ed25519 signature |
The permission callback verifies these headers:
| Header | Use |
|---|---|
webhook-id | Object-cache idempotency key |
webhook-timestamp | Five-minute replay window |
webhook-signature | v1ed,BASE64 Ed25519 signature |
webhook-event-type | Supported pull request event name |
WordPress hashes webhook-id.webhook-timestamp.rawBody with SHA-256. It verifies the lowercase hexadecimal digest string against the Ed25519 public keys from https://api.cursor.com/v1/origin/keys.
Valid requests return { "ok": true } with HTTP 200. A disabled factory returns the same response and queues no work. Duplicate, unsupported, and ignored events also return HTTP 200. Accepted events queue prc_slack_factory_delivery.
Origin signature errors
| Code | Status | Meaning |
|---|---|---|
origin_signature_missing | 400 | A required header is missing or malformed |
origin_payload_invalid | 400 | The body is not a JSON object |
origin_replay_detected | 401 | The timestamp is outside the five-minute window |
origin_signature_invalid | 401 | No signature matches an Origin Ed25519 public key |
origin_keys_unavailable | 503 | WordPress cannot load the Origin public keys |
origin_keys_invalid | 503 | The Origin public-key response is invalid |
Slack signature errors
| Code | Status | Meaning |
|---|---|---|
slack_disabled | 403 | Chat is off or signing secret / workspace is missing |
missing_signature | 401 | Signature header absent |
replay_detected | 401 | Timestamp older than 5 minutes |
invalid_signature | 401 | Signature mismatch |
slack_team_missing | 403 | Team missing on the request |
slack_team_mismatch | 403 | Team does not match the configured workspace |
url_verification skips the signature check. Chat must still be enabled.