Build creator outreach into your stack

REST API, signed webhooks, CSV import/export, and OpenAPI spec. Everything you need to launch campaigns programmatically.

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.

bash
Authorization: Bearer sk_live_xxxxx
POST/api/v1/clients

Create a client

POST /api/v1/clients
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"
  }'
POST/api/v1/message-templates

Create message template

POST /api/v1/message-templates
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?"
  }'
POST/api/v1/campaigns

Create campaign

POST /api/v1/campaigns
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" }
  }'
POST/api/v1/campaigns/:id/targets

Upload targets

POST /api/v1/campaigns/:id/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
    }]
  }'
POST/api/v1/campaigns/:id/start

Start campaign

POST /api/v1/campaigns/:id/start
curl -X POST http://localhost:3000/api/v1/campaigns/CAMPAIGN_ID/start \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
GET/api/v1/campaigns/:id/results

Get results

GET /api/v1/campaigns/:id/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
POST/api/v1/webhooks

Register webhook

POST /api/v1/webhooks
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.

bash
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

CodeDescription
invalid_api_keyInvalid or revoked API key
missing_required_fieldA required field is missing
campaign_not_foundCampaign does not exist
client_not_foundClient does not exist
sender_not_availableNo active sender accounts
rate_limit_exceededAPI rate limit exceeded
target_duplicateTarget already contacted
target_suppressedTarget is on suppression list
usage_limit_exceededMonthly send limit reached
instagram_challenge_detectedInstagram challenge on sender
webhook_delivery_failedWebhook delivery failed