Authentication
The WAFlow Public API is authenticated with an API key. Every request under /api/v1 must include a valid key.
Create an API key
- Sign in to waflow.edesy.in and open the workspace you want to integrate.
- Go to Settings → API Keys.
- Click Create API Key, give it a name, and copy the key.
Note: The full key is shown only once at creation — store it securely (e.g. a secrets manager). Keys are prefixed
wc_and are scoped to a single workspace. You can revoke a key at any time from the same screen.
Send the key
Provide the key on every request using either header:
X-API-Key: wc_your_api_key
or
Authorization: Bearer wc_your_api_key
cURL Example:
curl "https://waflow.edesy.in/api/v1/contacts" \
-H "X-API-Key: wc_your_api_key"
JavaScript Example:
const res = await fetch('https://waflow.edesy.in/api/v1/contacts', {
headers: { 'X-API-Key': process.env.WAFLOW_API_KEY }
});
const data = await res.json();
Scopes
Each API key carries a set of scopes that control which operations it may perform. A request to an endpoint the key isn't scoped for returns 403 INSUFFICIENT_SCOPE.
| Scope | Grants |
|---|---|
messages.send |
Send individual messages (POST /messages) |
campaigns.create |
Create and start campaigns (POST /send) |
campaigns.read |
Read campaign status |
templates.read |
List, read, and sync templates |
templates.write |
Create/submit and delete templates |
contacts.read |
List and read contacts and lists |
contacts.write |
Create, update, and delete contacts and lists |
New keys are granted all scopes by default. You can narrow a key's scopes when creating it (e.g. a send‑only key with just messages.send).
Rate limits
| Limit | Value |
|---|---|
| Per API key | 100 requests / 15 minutes (configurable per key) |
| Per IP (unauthenticated guard) | 600 requests / 15 minutes |
Every response includes standard rate‑limit headers:
RateLimit-Limit: 100
RateLimit-Remaining: 97
RateLimit-Reset: 812
When the limit is exceeded you receive 429:
{
"success": false,
"error": "Too many requests",
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded for this API key."
}
Error responses
Missing API key (401):
{
"success": false,
"error": "API key is required",
"code": "MISSING_API_KEY",
"message": "Include your API key in the 'X-API-Key' header or 'Authorization: Bearer <key>' header"
}
Invalid or revoked key (401):
{
"success": false,
"error": "Invalid API key",
"code": "INVALID_API_KEY",
"message": "The provided API key is not valid or has been revoked"
}
Insufficient scope (403):
{
"success": false,
"error": "Insufficient API key permissions",
"code": "INSUFFICIENT_SCOPE",
"message": "This API key lacks the 'templates.write' permission.",
"requiredScope": "templates.write"
}
Security best practices
- Treat API keys like passwords — never commit them to source control or expose them in client‑side code.
- Use a separate key per integration so you can revoke one without affecting others.
- Prefer least‑privilege scopes (e.g. a
messages.send‑only key for a notification service). - Rotate keys periodically; revoke immediately if one may be compromised.