Authentication
Every request to the IG Layers API must include an API key in the Authorization header. Generate keys from the dashboard under API Keys. Keys are hashed at rest and shown only once at creation. Revoke compromised keys immediately.
Authorization: Bearer sk_live_xxxxx/api/v1/clientsCreate a client
curl -X POST http://localhost:3000/api/v1/clients \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Brand",
"externalId": "acme_001"
}'/api/v1/message-templatesCreate message template
curl -X POST http://localhost:3000/api/v1/message-templates \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Creator Intro",
"body": "Hi {{firstName}}, love your {{category}} content! Open to a collab?"
}'/api/v1/campaignsCreate campaign
curl -X POST http://localhost:3000/api/v1/campaigns \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "YOUR_CLIENT_ID",
"name": "Creator Outreach May 2026",
"messageTemplateId": "YOUR_TEMPLATE_ID",
"dailyLimit": 50,
"hourlyLimit": 8,
"metadata": { "source": "agent_workflow" }
}'/api/v1/campaigns/:id/targetsUpload targets
curl -X POST http://localhost:3000/api/v1/campaigns/CAMPAIGN_ID/targets \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"targets": [{
"instagramUsername": "creatorname",
"profileUrl": "https://instagram.com/creatorname",
"fullName": "Creator Name",
"firstName": "Creator",
"category": "fitness",
"followerCount": 24000
}]
}'/api/v1/campaigns/:id/startStart campaign
curl -X POST http://localhost:3000/api/v1/campaigns/CAMPAIGN_ID/start \
-H "Authorization: Bearer sk_live_YOUR_KEY"/api/v1/campaigns/:id/resultsGet results
# JSON results
curl http://localhost:3000/api/v1/campaigns/CAMPAIGN_ID/results \
-H "Authorization: Bearer sk_live_YOUR_KEY"
# CSV export
curl "http://localhost:3000/api/v1/campaigns/CAMPAIGN_ID/results?format=csv" \
-H "Authorization: Bearer sk_live_YOUR_KEY" -o results.csv/api/v1/webhooksRegister webhook
curl -X POST http://localhost:3000/api/v1/webhooks \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/iglayers",
"events": ["message.sent", "reply.received", "campaign.completed"]
}'Verify webhook signature
Webhooks are signed with HMAC SHA256. Compare the X-IG-Layers-Signature header against the raw request body using your endpoint secret.
const crypto = require("crypto");
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const valid = crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(signature, "hex")
);Webhook events
campaign.created · campaign.started · campaign.paused · campaign.resumed · campaign.completed target.queued · message.sent · message.failed · message.skipped · reply.received sender.warning · sender.challenged · sender.disabled
Error codes
All errors return JSON: { "error": { "code": "...", "message": "..." } }
Error reference
| Code | Description |
|---|---|
| invalid_api_key | Invalid or revoked API key |
| missing_required_field | A required field is missing |
| campaign_not_found | Campaign does not exist |
| client_not_found | Client does not exist |
| sender_not_available | No active sender accounts |
| rate_limit_exceeded | API rate limit exceeded |
| target_duplicate | Target already contacted |
| target_suppressed | Target is on suppression list |
| usage_limit_exceeded | Monthly send limit reached |
| instagram_challenge_detected | Instagram challenge on sender |
| webhook_delivery_failed | Webhook delivery failed |