Skip to main content

Overview

Bulk operations allow you to create or delete up to 100 links in a single API request. This is perfect for:
  • Launching marketing campaigns with many variations
  • Migrating links from another service
  • Cleaning up expired campaign links
  • Automating link generation at scale
Create up to 100 links in one request using POST /v1/links/bulk.

Basic Example

curl -X POST https://api.bouncy.ai/v1/links/bulk \
  -H "X-Api-Key: bcy_live_pk_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "links": [
      {
        "url": "https://example.com/page1",
        "slug": "page1",
        "title": "Page 1"
      },
      {
        "url": "https://example.com/page2",
        "slug": "page2",
        "title": "Page 2"
      },
      {
        "url": "https://example.com/page3",
        "slug": "page3",
        "title": "Page 3"
      }
    ]
  }'

Response Format

{
  "created": [
    {
      "id": "link_abc123",
      "shortUrl": "https://bouncy.link/page1",
      "slug": "page1",
      "destination": "https://example.com/page1"
    },
    {
      "id": "link_def456",
      "shortUrl": "https://bouncy.link/page2",
      "slug": "page2",
      "destination": "https://example.com/page2"
    }
  ],
  "failed": [
    {
      "index": 2,
      "slug": "page3",
      "error": {
        "code": "slug_already_exists",
        "message": "The slug 'page3' is already in use"
      }
    }
  ],
  "summary": {
    "total": 3,
    "succeeded": 2,
    "failed": 1
  }
}
Response Fields:
  • created - Array of successfully created links
  • failed - Array of links that failed with error details
  • summary - Count of total, succeeded, and failed operations
Partial success is supported - if some links fail, the successful ones are still created.

Real-World Examples

Marketing Campaign with UTM Parameters

Generate 50 links for a social media campaign across platforms:
const platforms = ['facebook', 'instagram', 'twitter', 'linkedin', 'tiktok'];
const contentTypes = ['story', 'post', 'ad', 'carousel'];

const links = [];

platforms.forEach(platform => {
  contentTypes.forEach(type => {
    links.push({
      url: `https://example.com/campaign?utm_source=${platform}&utm_medium=${type}&utm_campaign=summer2026`,
      slug: `summer-${platform}-${type}`,
      title: `Summer Campaign - ${platform} ${type}`,
      tags: ['summer2026', platform, type]
    });
  });
});

const response = await fetch('https://api.bouncy.ai/v1/links/bulk', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'bcy_live_pk_YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ links })
});

Import from CSV

Read links from a CSV file and bulk create:
import fs from 'fs';
import csvParser from 'csv-parser';

const links = [];

fs.createReadStream('links.csv')
  .pipe(csvParser())
  .on('data', (row) => {
    links.push({
      url: row.destination,
      slug: row.slug,
      title: row.title,
      tags: row.tags?.split(',') || []
    });
  })
  .on('end', async () => {
    // Process in batches of 100
    for (let i = 0; i < links.length; i += 100) {
      const batch = links.slice(i, i + 100);

      const response = await fetch('https://api.bouncy.ai/v1/links/bulk', {
        method: 'POST',
        headers: {
          'X-Api-Key': 'bcy_live_pk_YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ links: batch })
      });

      const result = await response.json();
      console.log(`Batch ${i / 100 + 1}: Created ${result.created.length}, Failed ${result.failed.length}`);
    }
  });
Delete up to 100 links in one request using DELETE /v1/links/bulk.

Example

curl -X DELETE https://api.bouncy.ai/v1/links/bulk \
  -H "X-Api-Key: bcy_live_pk_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "linkIds": ["link_abc123", "link_def456", "link_ghi789"]
  }'

Response

{
  "deleted": ["link_abc123", "link_def456"],
  "failed": [
    {
      "linkId": "link_ghi789",
      "error": {
        "code": "link_not_found",
        "message": "Link not found"
      }
    }
  ],
  "summary": {
    "total": 3,
    "succeeded": 2,
    "failed": 1
  }
}
Combine GET /v1/links with bulk delete to remove all links with a specific tag:
// Step 1: Get all links with tag "expired"
const response = await fetch('https://api.bouncy.ai/v1/links?tag=expired&limit=100', {
  headers: { 'X-Api-Key': 'bcy_live_pk_YOUR_API_KEY' }
});

const { data: links } = await response.json();
const linkIds = links.map(link => link.id);

// Step 2: Bulk delete
if (linkIds.length > 0) {
  const deleteResponse = await fetch('https://api.bouncy.ai/v1/links/bulk', {
    method: 'DELETE',
    headers: {
      'X-Api-Key': 'bcy_live_pk_YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ linkIds })
  });

  const result = await deleteResponse.json();
  console.log(`Deleted ${result.deleted.length} expired links`);
}

Best Practices

Always check the failed array in the response:
const result = await response.json();

if (result.failed.length > 0) {
  console.error(`${result.failed.length} links failed:`);
  result.failed.forEach(failure => {
    console.error(`  - Slug "${failure.slug}": ${failure.error.message}`);
  });
}

console.log(`Successfully created ${result.created.length} links`);
Each bulk request counts as 1 request toward your rate limit, regardless of how many links are in it. This makes bulk operations very efficient!Example: Creating 100 links individually = 100 requests. Creating 100 links with bulk = 1 request.
When processing multiple batches, add a small delay to avoid overwhelming the API:
for (const batch of batches) {
  await createBatch(batch);
  await new Promise(resolve => setTimeout(resolve, 1000)); // 1 second delay
}

Error Handling

Quota Exceeded

If you exceed your plan’s link limit, the entire bulk request fails:
{
  "error": {
    "code": "quota_exceeded",
    "message": "Creating 100 links would exceed your plan limit (950/1000 used)",
    "currentLinks": 950,
    "requestedLinks": 100,
    "maxLinks": 1000
  }
}
Solution: Delete unused links or upgrade your plan. If individual links fail validation, they appear in the failed array:
{
  "created": [...],
  "failed": [
    {
      "index": 0,
      "slug": "invalid-url",
      "error": {
        "code": "invalid_url",
        "message": "The URL must be a valid HTTP or HTTPS URL"
      }
    }
  ]
}
Fix the invalid links and retry only the failed ones.

Next Steps