Skipline API Referencev1

The Skipline REST API lets you interact with your waitlist campaigns programmatically. Add signups from your own frontend, fetch your waitlist to display in your app, look up individual subscribers, and pull campaign stats — all with a simple HTTP API.

The Skipline API is currently in beta. Endpoints and response shapes may change. We will announce breaking changes with at least 14 days notice.

Authentication

All API requests must be authenticated with an API key. Pass your key in the Authorization header as a Bearer token.

http
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

You can generate API keys from your Skipline dashboard under Settings → API Keys. Keys start with sk_live_. Each key is shown only once when created — store it somewhere safe immediately.

Never expose your API key in client-side JavaScript or public repositories. Always make API calls from your server.

Example Request

bash
curl https://skipline.tech/api/v1/campaign \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -G \
  --data-urlencode "slug=my-product"

Base URL

All API endpoints are relative to the following base URL:

text
https://skipline.tech/api/v1

All requests and responses use JSON. Include the Content-Type: application/json header on all POST requests.

Rate Limiting

The API is rate limited to 100 requests per 60 seconds per API key. Rate limit information is returned in the response headers on every request.

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window (always 100)
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp in milliseconds when the window resets

When you exceed the rate limit the API returns a 429 Too Many Requests response. Wait until the X-RateLimit-Reset time before retrying.

json
{
  "error": "Rate limit exceeded. Try again after 1704067260000",
  "code": "RATE_LIMITED"
}

Errors

Skipline uses standard HTTP status codes. All error responses include a human-readable error message and a machine-readable code string.

CodeHTTP StatusDescription
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403Valid key but wrong account for this resource
NOT_FOUND404The requested resource does not exist
VALIDATION_ERROR400Missing or invalid request parameters
CONFLICT409Resource already exists (e.g. duplicate email)
RATE_LIMITED429Too many requests
INTERNAL_ERROR500Something went wrong on our end

Example Error Response

json
{
  "error": "This email is already on the waitlist",
  "code": "CONFLICT"
}

GET /signups

GET/api/v1/signupsFetch all signups for a campaign

Returns a paginated list of all signups for a campaign ordered by position ascending by default.

Query Parameters

ParameterTypeRequiredDescription
campaign_idstringone of these two is requiredUUID of the campaign
slugstringone of these two is requiredSlug of the campaign (alternative to campaign_id)
pageintegeroptionalPage number, default 1
limitintegeroptionalResults per page, default 50, max 500
sortstringoptionalSort field: position, created_at, referral_count. Default: position
orderstringoptionalasc or desc. Default: asc

Example Request

bash
curl https://skipline.tech/api/v1/signups \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -G \
  --data-urlencode "slug=my-product" \
  --data-urlencode "limit=10" \
  --data-urlencode "sort=referral_count" \
  --data-urlencode "order=desc"

Example Response

json
{
  "data": {
    "signups": [
      {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "email": "jane@example.com",
        "position": 1,
        "referral_count": 14,
        "ref_code": "jane42",
        "referred_by": null,
        "is_early_access": true,
        "anon_name": "Silent Fox",
        "anon_emoji": "🦊",
        "created_at": "2026-01-12T08:32:00Z"
      }
    ],
    "pagination": {
      "total": 847,
      "page": 1,
      "limit": 10,
      "total_pages": 85,
      "has_next": true,
      "has_prev": false
    }
  },
  "meta": {
    "campaign_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "timestamp": "2026-01-12T09:00:00Z"
  }
}

The anon_name and anon_emoji fields are generated deterministically from the signup id. The same signup always gets the same name. These are the values shown on the public waitlist leaderboard.

POST /signups

POST/api/v1/signupsAdd someone to the waitlist

Adds a new signup to your waitlist. Triggers the referral mechanic if a ref_code is provided. Sends a confirmation email to the new signup and a referral notification email to the referrer.

Request Body

ParameterTypeRequiredDescription
campaign_idstringone of these two is requiredUUID of the campaign
slugstringone of these two is requiredSlug of the campaign
emailstringrequiredEmail address of the person joining
ref_codestringoptionalReferral code of the person who referred them. Triggers referral mechanics.

Example Request

bash
curl -X POST https://skipline.tech/api/v1/signups \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "my-product",
    "email": "newuser@example.com",
    "ref_code": "jane42"
  }'

Example Response (201 Created)

json
{
  "data": {
    "signup": {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "email": "newuser@example.com",
      "position": 423,
      "ref_code": "new99x",
      "referral_count": 0,
      "is_early_access": false,
      "created_at": "2026-01-12T09:05:00Z"
    }
  },
  "meta": {
    "campaign_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "timestamp": "2026-01-12T09:05:00Z"
  }
}

Possible Errors

StatusCodeWhen
400VALIDATION_ERROREmail is missing or invalid format
409CONFLICTEmail is already on this waitlist
404NOT_FOUNDCampaign not found

GET /signups/:email

GET/api/v1/signups/:emailLook up a specific signup

Returns the signup record for a specific email address including their current queue position, referral count, and a ready-to-share referral link.

The email address must be URL-encoded in the path. For example, user@example.com becomes user%40example.com.

Path Parameters

ParameterTypeRequiredDescription
emailstringrequiredURL-encoded email address of the signup

Query Parameters

ParameterTypeRequiredDescription
campaign_idstringone of these two is requiredUUID of the campaign
slugstringone of these two is requiredSlug of the campaign

Example Request

bash
curl "https://skipline.tech/api/v1/signups/jane%40example.com" \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -G \
  --data-urlencode "slug=my-product"

Example Response

json
{
  "data": {
    "signup": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "jane@example.com",
      "position": 1,
      "referral_count": 14,
      "ref_code": "jane42",
      "referred_by": null,
      "is_early_access": true,
      "anon_name": "Silent Fox",
      "anon_emoji": "🦊",
      "referral_link": "https://skipline.tech/w/my-product?ref=jane42",
      "created_at": "2026-01-12T08:32:00Z"
    }
  },
  "meta": {
    "campaign_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "timestamp": "2026-01-12T09:10:00Z"
  }
}

DELETE /signups/:email

DELETE/api/v1/signups/:emailRemove someone from the waitlist

Permanently removes a signup from the waitlist. Also deletes all referral records associated with this signup. This action cannot be undone.

Deleting a signup also removes their referral history. The positions of other signups are not automatically recalculated after deletion.

Path Parameters

ParameterTypeRequiredDescription
emailstringrequiredURL-encoded email address of the signup to delete

Query Parameters

ParameterTypeRequiredDescription
campaign_idstringone of these two is requiredUUID of the campaign
slugstringone of these two is requiredSlug of the campaign

Example Request

bash
curl -X DELETE "https://skipline.tech/api/v1/signups/jane%40example.com" \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -G \
  --data-urlencode "slug=my-product"

Example Response

json
{
  "data": {
    "deleted": true,
    "email": "jane@example.com"
  },
  "meta": {
    "campaign_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "timestamp": "2026-01-12T09:15:00Z"
  }
}

GET /campaign

GET/api/v1/campaignFetch campaign stats

Returns campaign details and computed analytics stats including total signups, referral count, viral coefficient, and referral conversion rate.

The viral coefficient is the average number of referrals per active referrer. A coefficient above 1.0 means your waitlist is growing virally — each referrer brings in more than one new signup on average.

Query Parameters

ParameterTypeRequiredDescription
campaign_idstringone of these two is requiredUUID of the campaign
slugstringone of these two is requiredSlug of the campaign

Example Request

bash
curl https://skipline.tech/api/v1/campaign \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx" \
  -G \
  --data-urlencode "slug=my-product"

Example Response

json
{
  "data": {
    "campaign": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "My Product Launch",
      "slug": "my-product",
      "headline": "The AI tool your team has been waiting for",
      "is_live": true,
      "created_at": "2026-01-01T00:00:00Z"
    },
    "stats": {
      "total_signups": 847,
      "total_referrals": 312,
      "referral_conversion_rate": 36.8,
      "viral_coefficient": 1.43,
      "early_access_unlocked": 24,
      "top_position": 1,
      "signups_who_shared": 218
    }
  },
  "meta": {
    "campaign_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "timestamp": "2026-01-12T09:20:00Z"
  }
}

API Keys

API keys are generated from your Skipline dashboard under Settings → API Keys. Each key belongs to your account and has access to all campaigns under that account.

  • Keys start with sk_live_ followed by 64 random hex characters
  • Each key is shown only once at creation — copy it immediately
  • You can generate multiple keys and name them (e.g. “Production”, “Staging”)
  • Delete keys you no longer need from the dashboard
  • Keys do not expire but can be revoked at any time

SDKs & Examples

No official SDK yet — the API is simple enough to use with plain fetch or any HTTP client. Here are ready-to-use examples.

javascript
// Add someone to your waitlist
const response = await fetch('https://skipline.tech/api/v1/signups', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    slug: 'my-product',
    email: 'user@example.com',
    ref_code: 'abc123' // optional
  })
})

const { data } = await response.json()
console.log(`Added to waitlist at position #${data.signup.position}`)
console.log(`Their referral link: /w/my-product?ref=${data.signup.ref_code}`)

Changelog

January 2026
v1.0

Initial API release

REST API launched with five endpoints: GET /signups, POST /signups, GET /signups/:email, DELETE /signups/:email, GET /campaign. API key authentication with SHA-256 hashing. Rate limiting at 100 requests per 60 seconds.