PrunePath API

Programmatic access to create, manage, and analyze your short links. Build integrations, automate workflows, or connect PrunePath to tools like Apple Shortcuts, Zapier, or your own applications.

Base URLhttps://prunepath.com/api

Authentication

All API requests require a Bearer token. Create tokens from Settings → API Tokens. Tokens use a pp_ prefix and are shown only once at creation — store them securely.

bash
curl https://prunepath.com/api/links \
  -H "Authorization: Bearer pp_your_token_here"

Available Scopes

Each token is scoped to specific permissions. Request only the scopes you need.

links:readList and view your links
links:createCreate new short links
links:updateEdit existing links
links:deleteRemove links
links:read:analyticsView click analytics
webhooks:readList webhooks
webhooks:manageCreate, update, and delete webhooks

Tokens are stored as SHA-256 hashes. If you lose a token, revoke it and create a new one.

GET
/api/links

Retrieve all links belonging to the authenticated user.

Scopes:
links:read
Response
json
[
  {
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "userId": "u9x8y7z6-w5v4-3210-fedc-ba0987654321",
  "shortCode": "mylink",
  "destinationUrl": "https://example.com",
  "title": "My Link",
  "isActive": true,
  "expiresAt": null,
  "createdAt": "2026-05-04T10:00:00.000Z",
  "updatedAt": "2026-05-04T10:00:00.000Z"
}
]
POST
/api/links

Create a new short link. If shortCode is omitted, one is auto-generated.

Scopes:
links:create
Request Body
json
{
  "destinationUrl": "https://example.com",
  "shortCode": "mylink",
  "title": "My Link",
  "expiresAt": "2026-12-31T00:00:00Z"
}
Response — 201
json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "userId": "u9x8y7z6-w5v4-3210-fedc-ba0987654321",
  "shortCode": "mylink",
  "destinationUrl": "https://example.com",
  "title": "My Link",
  "isActive": true,
  "expiresAt": null,
  "createdAt": "2026-05-04T10:00:00.000Z",
  "updatedAt": "2026-05-04T10:00:00.000Z"
}

shortCode must be 3–20 characters: letters, numbers, hyphens, underscores.

If the short code is taken, you'll receive a 409 with suggested alternatives.

PATCH
/api/links/:id

Update fields on an existing link. Only include the fields you want to change.

Scopes:
links:update
Request Body
json
{
  "destinationUrl": "https://new-example.com",
  "title": "Updated Title",
  "isActive": false
}
Response
json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "userId": "u9x8y7z6-w5v4-3210-fedc-ba0987654321",
  "shortCode": "mylink",
  "destinationUrl": "https://example.com",
  "title": "My Link",
  "isActive": true,
  "expiresAt": null,
  "createdAt": "2026-05-04T10:00:00.000Z",
  "updatedAt": "2026-05-04T10:00:00.000Z"
}
DELETE
/api/links/:id

Permanently delete a link and all its associated click data.

Scopes:
links:delete
GET
/api/links/check/:shortCode

Check whether a short code is available before creating a link.

Scopes:
links:read
Response
json
{
  "available": false,
  "suggestions": ["mylink-1", "mylink-2x", "my-link"]
}

Analytics

GET
/api/analytics/overview

Get account-wide analytics including total clicks, link counts, and top-performing link.

Scopes:
links:read:analytics
Response
json
{
  "totalLinks": 42,
  "totalClicks": 12847,
  "activeLinks": 38,
  "topLink": {
    "shortCode": "mylink",
    "clicks": 3291
  }
}
GET
/api/analytics/link/:linkId

Get detailed analytics for a specific link, including clicks over time, referrers, and geographic data.

Scopes:
links:read:analytics
Query Parameters
rangePreset range: 7d, 30d, 90d, 12m
fromStart date (ISO 8601)
toEnd date (ISO 8601)
Response
json
{
  "linkId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "totalClicks": 3291,
  "clicksByDay": [
    { "date": "2026-05-01", "clicks": 142 },
    { "date": "2026-05-02", "clicks": 198 }
  ],
  "topReferrers": [
    { "referrer": "twitter.com", "clicks": 891 }
  ],
  "topCountries": [
    { "country": "US", "clicks": 1523 }
  ]
}

Token Management

These endpoints require session authentication (browser cookies). They cannot be accessed with API tokens.

GET
/api/tokens

List all API tokens for the authenticated user. Token values are not included — only metadata.

POST
/api/tokens

Create a new API token. The full token value is returned only in this response.

Request Body
json
{
  "name": "My Shortcut Token",
  "scopes": ["links:create", "links:read"],
  "expiresAt": "2027-01-01T00:00:00Z"
}
Response — 201
json
{
  "id": "tok_abc123",
  "name": "My Shortcut Token",
  "token": "pp_a1b2c3d4e5f6...",
  "scopes": ["links:create", "links:read"],
  "expiresAt": "2027-01-01T00:00:00.000Z",
  "createdAt": "2026-05-04T10:00:00.000Z"
}

The token field is only returned at creation. Store it immediately.

DELETE
/api/tokens/:id

Revoke an API token. It will immediately stop working for all future requests.

Error Handling

All errors return a consistent JSON structure with a machine-readable code and a human-readable message.

json
{
  "code": "VALIDATION_ERROR",
  "message": "destinationUrl is required and must be a valid URL"
}

Error Codes

CodeStatusDescription
UNAUTHORIZED401Missing or invalid authentication token
FORBIDDEN403Token lacks required scope for this action
VALIDATION_ERROR400Request body or parameters failed validation
NOT_FOUND404The requested resource does not exist
ALREADY_EXISTS409A resource with that identifier already exists
RATE_LIMIT_EXCEEDED429Too many requests — slow down
INTERNAL_ERROR500An unexpected server error occurred

Rate Limiting

API requests are rate-limited to ensure fair usage. When you exceed the limit, you'll receive a 429 response with a Retry-After header indicating how many seconds to wait.

Link creation, updates, and deletions
Rate limited
Token creation
5 per hour

Quick Start

Create your first short link in seconds. Replace pp_your_token_here with a token from Settings.

cURL

bash
curl -X POST https://prunepath.com/api/links \
  -H "Authorization: Bearer pp_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "destinationUrl": "https://example.com/my-long-url",
    "title": "My Short Link"
  }'

JavaScript (fetch)

javascript
const response = await fetch("https://prunepath.com/api/links", {
  method: "POST",
  headers: {
    "Authorization": "Bearer pp_your_token_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    destinationUrl: "https://example.com/my-long-url",
    title: "My Short Link",
  }),
});

const link = await response.json();
console.log(link.shortCode);
// => "a8kX2p"