Guides·Intermediate

REST API Integration

Integrate Attro into your application using the REST API. Create affiliates, record conversions, and retrieve analytics programmatically.

8 minLast updated June 13, 2026

Prerequisites

  • API key created in Attro dashboard
  • Familiarity with REST APIs
  • HTTP client (curl, Postman, or code)

The Attro REST API gives you programmatic access to your affiliate program. Create affiliates, generate tracking links, record conversions, and pull analytics data - all through simple HTTP requests.

API Capabilities

  • Manage affiliates (create, update, list)
  • Configure offers and commission structures
  • Generate and manage tracking links
  • Record conversions from any source
  • Retrieve analytics and reports
  • Manage payouts and balances

Base URL

https://get-attro.com/api/v1

All API endpoints are prefixed with /api/v1. Responses are JSON-formatted.

1

Authentication

All API requests require authentication via an API key. Keys are scoped to your organization and can have read-only or read-write permissions.

Create an API Key

  1. Go to Settings → API Keys in your admin dashboard
  2. Click "Create API Key"
  3. Enter a name (e.g., "Production Backend")
  4. Select permissions: Read-only or Read/Write
  5. Copy and securely store the key

Security: API keys are shown only once. Store them securely and never commit them to version control.

Using Your API Key

Include the key in the Authorization header:

curl https://get-attro.com/api/v1/affiliates \
  -H "Authorization: Bearer sk_live_abc123def456"

Key Formats

  • sk_live_* - Production keys
  • sk_test_* - Test/sandbox keys
2

List and Create Affiliates

Manage your affiliate roster programmatically.

List Affiliates

# List all affiliates
curl https://get-attro.com/api/v1/affiliates \
  -H "Authorization: Bearer sk_live_abc123"

# Filter by status and type
curl "https://get-attro.com/api/v1/affiliates?status=active&type=external&limit=50" \
  -H "Authorization: Bearer sk_live_abc123"

Query Parameters:

  • status - Filter by status (active, pending, inactive)
  • type - Filter by type (external, internal)
  • limit - Results per page (default: 20, max: 100)
  • offset - Pagination offset

Response Format

{
  "data": [
    {
      "id": "aff_abc123",
      "companyName": "Acme Corp",
      "displayName": "John Smith",
      "email": "[email protected]",
      "type": "external",
      "status": "active",
      "createdAt": "2026-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "total": 45,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  }
}

Create Affiliate

curl https://get-attro.com/api/v1/affiliates \
  -X POST \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "companyName": "Acme Corp",
    "displayName": "John Smith",
    "email": "[email protected]",
    "type": "external",
    "website": "https://acme.com",
    "paymentEmail": "[email protected]"
  }'

Required Fields:

  • displayName - Affiliate's display name
  • email - Contact email
  • type - "external" or "internal"

Optional Fields:

  • companyName - Company or brand name
  • website - Affiliate's website
  • paymentEmail - PayPal email for payouts
  • commissionOverride - Custom commission rate
3

Manage Offers

Configure what affiliates can promote and how they're compensated.

List Offers

# List all offers
curl https://get-attro.com/api/v1/offers \
  -H "Authorization: Bearer sk_live_abc123"

# Filter active offers only
curl "https://get-attro.com/api/v1/offers?isActive=true" \
  -H "Authorization: Bearer sk_live_abc123"

Create Offer

curl https://get-attro.com/api/v1/offers \
  -X POST \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Subscription",
    "url": "https://yourapp.com/premium",
    "description": "Our flagship product",
    "defaultCommissionType": "percentage",
    "defaultCommissionValue": 20,
    "attributionWindowDays": 30,
    "dailyCap": 100,
    "isActive": true
  }'

Offer Fields

  • name - Internal name for the offer
  • url - Destination URL for tracking links
  • defaultCommissionType - "percentage" or "fixed"
  • defaultCommissionValue - Rate (20 for 20% or 50 for $50)
  • attributionWindowDays - Click validity period
  • dailyCap - Max conversions per day (0 = unlimited)

Update Offer

curl https://get-attro.com/api/v1/offers/off_abc123 \
  -X PATCH \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "defaultCommissionValue": 25,
    "dailyCap": 200
  }'
4

Create Tracking Links

Generate unique tracking links that affiliates share to promote your offers.

List Tracking Links

# List all tracking links
curl https://get-attro.com/api/v1/tracking-links \
  -H "Authorization: Bearer sk_live_abc123"

# Filter by affiliate
curl "https://get-attro.com/api/v1/tracking-links?affiliateId=aff_abc123" \
  -H "Authorization: Bearer sk_live_abc123"

Create Tracking Link

curl https://get-attro.com/api/v1/tracking-links \
  -X POST \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "affiliateId": "aff_abc123",
    "offerId": "off_xyz789",
    "customUrl": "https://yourapp.com/special-promo"
  }'

Response

{
  "data": {
    "id": "link_def456",
    "affiliateId": "aff_abc123",
    "offerId": "off_xyz789",
    "code": "a1b2c3d4",
    "trackingUrl": "https://get-attro.com/r/a1b2c3d4",
    "destinationUrl": "https://yourapp.com/special-promo",
    "clicks": 0,
    "conversions": 0,
    "createdAt": "2026-01-20T14:00:00Z"
  }
}

The trackingUrl is what affiliates share. When clicked, users are redirected to the destinationUrl.

Custom URLs

If customUrl is not provided, the link uses the offer's default URL. Use custom URLs for:

  • Campaign-specific landing pages
  • A/B testing different pages
  • Promotional pages with special pricing
5

Record Conversions

Record conversions manually when you can't use webhooks, or for non-standard conversion sources.

List Conversions

# List recent conversions
curl https://get-attro.com/api/v1/conversions \
  -H "Authorization: Bearer sk_live_abc123"

# Filter by status and affiliate
curl "https://get-attro.com/api/v1/conversions?status=pending&affiliateId=aff_abc123" \
  -H "Authorization: Bearer sk_live_abc123"

Record Conversion

curl https://get-attro.com/api/v1/conversions \
  -X POST \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "affiliateId": "aff_abc123",
    "offerId": "off_xyz789",
    "externalId": "your-transaction-id-12345",
    "externalSource": "custom_checkout",
    "amount": 99.00,
    "currency": "USD",
    "customerEmail": "[email protected]",
    "metadata": {
      "plan": "premium",
      "period": "annual"
    }
  }'

Required Fields

  • affiliateId - Affiliate to credit
  • offerId - Offer this conversion is for
  • externalId - Your unique transaction ID
  • amount - Sale amount (for commission calculation)

Optional Fields

  • externalSource - Source identifier (stripe, revenuecat, api, etc.)
  • currency - ISO currency code (default: USD)
  • customerEmail - Customer's email
  • metadata - Custom key-value data

Duplicate Prevention

The externalId field prevents duplicate conversions. If you submit the same externalId twice, the API returns 409 Conflict.

{
  "error": {
    "code": "DUPLICATE_CONVERSION",
    "message": "Conversion with externalId 'your-transaction-id-12345' already exists"
  }
}
6

Error Handling

The API uses standard HTTP status codes and returns detailed error information.

Status Codes

| Status | Meaning                              |
|--------|--------------------------------------|
| 200    | Success                              |
| 201    | Created                              |
| 400    | Invalid request body or parameters   |
| 401    | Missing or invalid API key           |
| 403    | API key lacks required permission    |
| 404    | Resource not found                   |
| 409    | Conflict (duplicate conversion)      |
| 429    | Rate limit exceeded                  |
| 500    | Server error                         |

Error Response Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request body",
    "details": {
      "email": "Invalid email format",
      "amount": "Must be a positive number"
    }
  }
}

Common Error Codes

  • INVALID_API_KEY - Key is malformed or revoked
  • INSUFFICIENT_PERMISSIONS - Key lacks read/write access
  • VALIDATION_ERROR - Request body validation failed
  • NOT_FOUND - Requested resource doesn't exist
  • DUPLICATE_CONVERSION - externalId already used
  • RATE_LIMITED - Too many requests

Handling Errors in Code

async function createAffiliate(data) {
  const response = await fetch('https://get-attro.com/api/v1/affiliates', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  });

  if (!response.ok) {
    const error = await response.json();

    switch (response.status) {
      case 400:
        throw new Error(`Validation error: ${error.error.message}`);
      case 401:
        throw new Error('Invalid API key');
      case 429:
        // Implement retry with backoff
        await sleep(error.error.retryAfter * 1000);
        return createAffiliate(data);
      default:
        throw new Error(`API error: ${error.error.message}`);
    }
  }

  return response.json();
}
7

Rate Limits and Pagination

The API has rate limits to ensure fair usage and includes pagination for large result sets.

Rate Limits

  • Standard: 100 requests per minute per API key
  • Burst: Up to 20 requests per second

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1706288400

Handling Rate Limits

async function apiRequest(url, options) {
  const response = await fetch(url, options);

  if (response.status === 429) {
    const resetTime = response.headers.get('X-RateLimit-Reset');
    const waitMs = (parseInt(resetTime) * 1000) - Date.now();

    console.log(`Rate limited. Waiting ${waitMs}ms`);
    await sleep(Math.max(waitMs, 1000));

    return apiRequest(url, options); // Retry
  }

  return response;
}

Pagination

List endpoints return paginated results:

# First page (default: 20 items)
curl "https://get-attro.com/api/v1/affiliates" \
  -H "Authorization: Bearer sk_live_abc123"

# Custom page size and offset
curl "https://get-attro.com/api/v1/affiliates?limit=50&offset=100" \
  -H "Authorization: Bearer sk_live_abc123"

Parameters:

  • limit - Items per page (1-100, default: 20)
  • offset - Number of items to skip

Iterating All Results

async function getAllAffiliates() {
  const affiliates = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await fetch(
      `https://get-attro.com/api/v1/affiliates?limit=${limit}&offset=${offset}`,
      { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    );
    const data = await response.json();

    affiliates.push(...data.data);

    if (!data.pagination.hasMore) break;
    offset += limit;
  }

  return affiliates;
}

API Integration Complete

You now have everything you need to integrate Attro into your application. The REST API provides full control over your affiliate program.

Quick Reference

Base URL:     https://get-attro.com/api/v1
Auth Header:  Authorization: Bearer sk_live_xxx
Content-Type: application/json

Endpoints:
  GET    /affiliates         List affiliates
  POST   /affiliates         Create affiliate
  GET    /offers             List offers
  POST   /offers             Create offer
  GET    /tracking-links     List tracking links
  POST   /tracking-links     Create tracking link
  GET    /conversions        List conversions
  POST   /conversions        Record conversion

Next Steps

Questions about the API? Contact us at [email protected].

Need help with integration?

Our support team is here to help you get set up.