API Documentation
POST
/v2/shorten/batchIndie & Pro Plans OnlyCreates multiple shortened URLs in a single request with API key authentication. Accepts an array of up to 50 URLs. Returns a 200 OK array of results for both successes and failures within the batch.
Plan Restriction: Batch URL shortening is exclusively available to accounts on the Indie ($29/mo) and Pro ($99/mo) plans. Requests made with API keys on Free or Hobby plans are rejected with an HTTP 403 Forbidden response.
Request Headers
| Parameter | Type | Required | Plan | Description |
|---|---|---|---|---|
| Authorization | string | Required | All Plans | Your API key as a Bearer token in the Authorization header. Returns a 401 error if missing, invalid, or revoked. |
| Content-Type | string | Required | All Plans | Must be set to "application/json". |
Request Body Schema
The root request body must contain a single urls array. If the array is empty or contains more than 50 items, a 400 Bad Request is returned.
| Parameter | Type | Required | Plan | Description |
|---|---|---|---|---|
| urls | array | Required | Indie+ | An array of URL objects to be shortened (minimum 1, maximum 50 items). |
Array Item Schema
Each object in the urls array represents a single link to shorten.
| Parameter | Type | Required | Plan | Description |
|---|---|---|---|---|
| url | string | Required | Indie+ | The full destination URL to shorten. Must include the protocol (http:// or https://). |
| alias | string | Optional | Indie+ | A custom short code (3 to 50 characters, alphanumeric and hyphens only). |
| password | string | Optional | Indie+ | A password (4 to 100 characters) that visitors must enter before being redirected. |
| expiresIn | number | Optional | Indie+ | Time-to-live in seconds (minimum 60s). The link is automatically purged after this duration. |
| maxClicks | number | Optional | Indie+ | Maximum number of redirects allowed before the link expires. |
Request Examples
Batch of 3 URLs with a mix of configurations:
bash
curl -X POST https://api.plung.co/v2/shorten/batch \
-H "Authorization: Bearer your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"urls": [
{
"url": "https://example.com/first-link"
},
{
"url": "https://example.com/newsletter",
"alias": "newsletter-2026"
},
{
"url": "https://example.com/secret",
"password": "secure-password",
"expiresIn": 86400,
"maxClicks": 100
}
]
}'Success Response (Partial Failures Handled)
Status: 200 OK
Important: A batch request returns HTTP 200 OK unless the root payload is malformed or unauthorized. If individual items fail validation (e.g. alias already taken), they will appear in the
results array with "success": false.json
{
"results": [
{
"index": 0,
"success": true,
"shortUrl": "https://plu.ng/abc12345",
"shortCode": "abc12345",
"url": "https://example.com/first-link"
},
{
"index": 1,
"success": false,
"error": "Alias is already taken"
},
{
"index": 2,
"success": true,
"shortUrl": "https://plu.ng/newsletter-2026",
"shortCode": "newsletter-2026",
"url": "https://example.com/secret",
"expiresAt": "2026-09-30T14:00:00.000Z",
"maxClicks": 100
}
]
}Error Responses
| Status | Cause | Message |
|---|---|---|
400 | Array bounds exceeded | "The urls array cannot exceed 50 items" or "The urls array must contain at least 1 item" |
401 | Missing / Invalid API key | "API key required. Pass your key as: Authorization: Bearer <key>" |
403 | Plan upgrade required (Free / Hobby) | "Your current plan does not include this feature." |
429 | Rate limit exceeded | "Rate limit exceeded. Try again in the next minute." |
503 | Maintenance mode active | "Service is temporarily unavailable for maintenance" |
Plan-Gating Error Example (403 Forbidden):
json
{
"statusCode": 403,
"timestamp": "2026-09-29T13:39:01.892Z",
"path": "/v2/shorten/batch",
"method": "POST",
"message": "Your current plan does not include this feature."
}