API Integration
Integrate with Resonance by sending events and receiving webhooks.
Authentication
All requests to the Resonance API must include a valid HMAC-SHA256 signature. Your security key is available in the Partner Portal under Settings > API Keys.
Include the signature in the X-Resonance-Signature request header. The signature is computed over the raw JSON payload body using your secret key.
const crypto = require('crypto');
function verifySignature(payload, signature, secretKey) {
const expected = crypto
.createHmac('sha256', secretKey)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Requests with missing or invalid signatures are rejected with a 401 INVALID_SIGNATURE response.
Sending Events
Send a POST request to the event handler endpoint to trigger a reward event for a Discord user.
Endpoint
POST https://api.resonance.bot/v1/events
Request Headers
| Header | Value |
|---|---|
Content-Type | application/json |
X-Resonance-Signature | HMAC-SHA256 hex signature of the request body |
Request Body
{
"brand_id": "0x...",
"event_type": "custom_event",
"user_id": "discord_user_id",
"server_id": "guild_id",
"amount": 50,
"metadata": {}
}
| Field | Type | Required | Description |
|---|---|---|---|
brand_id | string | Yes | Your brand's registered wallet address |
event_type | string | Yes | One of the supported event types (see below) |
user_id | string | Yes | The Discord user ID of the recipient |
server_id | string | Yes | The Discord guild ID where the event occurred |
amount | number | No | Token amount to award. Defaults to the event's configured amount if omitted. |
metadata | object | No | Arbitrary key-value data attached to the event record |
Event Types
| Event Type | Description |
|---|---|
daily_checkin | Daily streak check-in |
channel_message | Message in monitored channel |
message_quality | Quality message reward |
reaction_threshold | Message reached reaction threshold |
boost_event | Server boost detected |
voice_participation | Voice channel activity |
custom_event | Custom-defined event |
Event types must be enabled for your brand before they can be triggered. Enable or disable event types via /config events in your Discord server.
Response Format
Success — 200 OK
{
"success": true,
"event_id": "evt_01HXYZ...",
"user_id": "discord_user_id",
"amount_awarded": 50,
"new_balance": 1250
}
Error — 4xx / 5xx
{
"success": false,
"error": {
"code": "COOLDOWN_ACTIVE",
"message": "User is currently in cooldown for this event type.",
"retry_after": 3420
}
}
HTTP Status Codes
| Status | Meaning |
|---|---|
200 | Event processed successfully |
400 | Malformed request or invalid field values |
401 | Signature verification failed |
429 | Rate limit exceeded |
500 | Internal server error |
Rate Limits
Resonance enforces two layers of rate limiting to ensure fair distribution and prevent abuse.
Per-event cooldowns — Each event type has a configurable cooldown window per user. A user cannot trigger the same event type again until the cooldown expires. The retry_after field in error responses gives the remaining cooldown in seconds.
Per-user daily limits — Each user has a daily cap on the total number of reward events they can receive across all event types. Once a user reaches their daily limit, further events for that user are silently accepted but not processed until the following UTC day.
API-level limits — Requests from a single brand are limited to 60 requests per minute. Exceeding this returns a 429 response with a Retry-After header indicating when you may resume.
Cooldown durations and daily limits are configured per event type via /config events.
Error Codes
| Code | Description | Resolution |
|---|---|---|
INVALID_SIGNATURE | HMAC verification failed | Check that you are signing the correct payload with the correct security key from the Partner Portal |
BRAND_NOT_FOUND | Brand ID not registered | Verify your brand_id matches the wallet address shown in the Partner Portal |
EVENT_DISABLED | Event type is disabled | Enable the event type via /config events in your Discord server |
COOLDOWN_ACTIVE | User is in cooldown for this event | Wait for the cooldown period to expire; check retry_after in the response |
INSUFFICIENT_BALANCE | Brand wallet has insufficient funds | Fund your brand wallet via the Partner Portal |
USER_DISABLED | User account is disabled | Check the user's status in the Partner Portal or via /user status |