New

Developer API

v0.1.0

The Nestuge Developer API is a brand-authenticated REST API. Read your products, transactions, hub members, and a product's customers; import members and customers; generate checkout links; and subscribe to webhooks. Everything your storefront does is available to your own tools.

Responses share a common envelope: status, message, and the payload under data. List endpoints paginate with limit and cursor query parameters and return hasMore and nextCursor alongside the items.

Base URLs

https://nestuge.com/api/v1  # Production

Authentication

Every request is authenticated with a brand API key sent in the x-nestuge-api header. Keys are created from your dashboard under Settings → Developer and come in two modes: nk_live_… for production and nk_test_… for test mode.

Each key is granted scopes such as products:read or webhooks:write; the scopes an endpoint needs are listed next to it in this reference. Verify a key with the ping endpoint. It returns your brand, the key mode, and the granted scopes.

Keep keys server-side. Never embed them in client-side code, and rotate a key from the dashboard if it leaks.

Request

curl https://nestuge.com/api/v1/ping \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "ok": true,
    "brandID": "a1b2c3d4e5",
    "mode": "test",
    "scopes": ["products:read", "webhooks:write"]
  }
}

Webhook events

Register an HTTPS endpoint with POST /webhooks (or from the dashboard) to receive events as they happen. The signing secret is returned once at creation and never again. Store it safely.

Every delivery is a JSON event envelope signed with an X-Nestuge-Signature header containing sha256=<hex>, an HMAC-SHA256 of the raw request body using your signing secret. Verify it with the Nestuge SDK before trusting a payload, and always verify against the raw body exactly as received: re-serialized JSON will not match the signature.

Respond with a 2xx status quickly; failed deliveries can be inspected and resent from the webhook deliveries endpoints below.

Event payload

{
  "id": "a1b2c3d4e5",
  "type": "transaction.succeeded",
  "created": "2026-07-06T10:00:00.000Z",
  "data": {
    // the transaction, purchase, or customer
    // the event is about
  }
}

verify-webhook.ts

import { constructEvent } from '@nestuge/sdk';

const event = await constructEvent({
  payload: rawRequestBody, // the raw, unmodified body string
  signature: request.headers['x-nestuge-signature'],
  secret: process.env.NESTUGE_WEBHOOK_SECRET,
});

switch (event.type) {
  case 'transaction.succeeded':
    // event.data is the transaction
    break;
}

Resources

Everything in this reference is plain HTTPS + JSON, so any HTTP client works, but the official SDK and example app are the fastest way to a working integration.

JavaScript / TypeScript SDK

@nestuge/sdk

The official SDK for the Developer API. Fully typed, zero runtime dependencies, and runs anywhere fetch does: Node.js 18+, Bun, Deno, and edge runtimes. Ships retries, cursor pagination helpers, typed errors, and webhook signature verification.

Example app: developer console

nestuge-dashboard

A small developer console built as the reference consumer of the SDK: connection status, members, products, transactions, and a webhook delivery log with a test-event form. Next.js App Router; every API call happens server-side, so your key never reaches the browser.

Terminal

npm install @nestuge/sdk

quickstart.ts

import Nestuge from '@nestuge/sdk';

const nestuge = new Nestuge({ apiKey: process.env.NESTUGE_API_KEY });

// Verify your key works
const { brandID, mode, scopes } = await nestuge.ping();

// List your customers
const { items } = await nestuge.customers.list({ limit: 50 });

Hubs


List hub members

GET/hubs/{hubID}/members
customers:read

Lists a hub's members (memberships), newest first.

Path parameters

hubID

string

required

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/hubs/a1b2c3d4e5/members" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "membershipId": "a1b2c3d4e5",
        "name": "Ada Lovelace",
        "email": "ada@example.com",
        "phone": "+2348012345678",
        "hubID": "a1b2c3d4e5",
        "status": "active",
        "plan": "string",
        "joinedAt": "2026-07-06T10:00:00.000Z"
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Get a hub member

GET/hubs/{hubID}/members/{id}
customers:read

Returns a single hub membership by its membership id.

Path parameters

hubID

string

required

id

string

required

Request

curl "https://nestuge.com/api/v1/hubs/a1b2c3d4e5/members/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "membershipId": "a1b2c3d4e5",
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": "+2348012345678",
    "hubID": "a1b2c3d4e5",
    "status": "active",
    "plan": "string",
    "joinedAt": "2026-07-06T10:00:00.000Z"
  }
}

Import members to a hub

POST/hubs/{hubID}/members/import
customers:write

Bulk-imports members into the hub. Send `records` as an array of objects; hubs collect only `fullName` and `email`, both required, e.g. `[{ "fullName": "Ada Lovelace", "email": "ada@example.com" }]`. Queues the import and returns how many records were accepted.

Path parameters

hubID

string

required

Body parameters

records

array of object

required

plan

string

Request

curl -X POST "https://nestuge.com/api/v1/hubs/a1b2c3d4e5/members/import" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      {}
    ]
  }'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "queued": true,
    "count": 10
  }
}

Payments


Generate a payment link

POST/payment-links
checkout:write

Creates a payment link for the given items and returns a link the customer can open to complete payment. Accepts the same payload as the web checkout. Every item must belong to the authenticated brand.

Body parameters

items

array of object

required

items.id

string

required

items.plan

string

required

items.type

string

required

items.hubID

string

items.affiliate

string

items.selected

array of string

items.count

number

items.customAmount

number

form

object

required

form.formData

object

required

form.formData.fullName

string

required

form.formData.email

string

required

form.formData.phone

string

form.guests

array of object

form.guests.id

string

required

form.guests.fullName

string

required

form.guests.email

string

required

currency

string

coupon

string

countryCode

string

addons

array of string

booking

object

address

object

deliveryLocation

string

pickupLocation

string

redirectUrl

string

utmRef

string

adClickID

string

adType

string

checkoutOtpVerificationSkipped

boolean

receive_emails

boolean

Request

curl -X POST "https://nestuge.com/api/v1/payment-links" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "id": "a1b2c3d4e5",
        "plan": "string",
        "type": "string",
        "hubID": "a1b2c3d4e5",
        "affiliate": "string",
        "selected": [
          "string"
        ],
        "count": 10,
        "customAmount": 5000
      }
    ],
    "form": {
      "formData": {
        "fullName": "Ada Lovelace",
        "email": "ada@example.com",
        "phone": "+2348012345678"
      },
      "guests": [
        {
          "id": "a1b2c3d4e5",
          "fullName": "Ada Lovelace",
          "email": "ada@example.com"
        }
      ]
    }
  }'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "link": "string"
  }
}

Ping


Verify an API key

GET/ping

Authenticated health check. Returns the resolved brand and granted scopes so developers can confirm their key works. Any valid key may call it (no scope required).

Request

curl "https://nestuge.com/api/v1/ping" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "ok": true,
    "brandID": "a1b2c3d4e5",
    "scopes": [
      "products:read"
    ]
  }
}

Products


List products

GET/products
products:read

Lists the brand's products (all types), newest first.

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/products" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "id": "a1b2c3d4e5",
        "type": "string",
        "status": "active",
        "title": "Design masterclass",
        "description": "A hands-on class covering the basics.",
        "imageUrl": "https://example.com/image.png",
        "url": "https://example.com/webhooks/nestuge",
        "visibility": "string",
        "isFree": true,
        "keywords": [
          "string"
        ],
        "createdAt": "2026-07-06T10:00:00.000Z",
        "updatedAt": "2026-07-06T10:00:00.000Z",
        "event": {
          "eventType": "string",
          "venue": "Lagos, Nigeria",
          "dateTime": "2026-07-06T10:00:00.000Z",
          "endDate": "2026-07-06T10:00:00.000Z"
        }
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Get a product

GET/products/{id}
products:read

Returns a single product owned by the brand, including its pricing tiers and content items.

Path parameters

id

string

required

Request

curl "https://nestuge.com/api/v1/products/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "type": "string",
    "status": "active",
    "title": "Design masterclass",
    "description": "A hands-on class covering the basics.",
    "imageUrl": "https://example.com/image.png",
    "url": "https://example.com/webhooks/nestuge",
    "visibility": "string",
    "isFree": true,
    "keywords": [
      "string"
    ],
    "createdAt": "2026-07-06T10:00:00.000Z",
    "updatedAt": "2026-07-06T10:00:00.000Z",
    "event": {
      "eventType": "string",
      "venue": "Lagos, Nigeria",
      "dateTime": "2026-07-06T10:00:00.000Z",
      "endDate": "2026-07-06T10:00:00.000Z"
    },
    "tiers": [
      {
        "id": "a1b2c3d4e5",
        "name": "Ada Lovelace",
        "type": "string",
        "price": {
          "amount": 5000,
          "currency": "USD"
        },
        "discount": {
          "amount": 5000,
          "currency": "USD"
        },
        "recurrence": {
          "periodic": "string",
          "count": 10,
          "interval": 10
        },
        "perks": [
          "string"
        ],
        "buttonText": "string",
        "timeBound": "2026-07-06T10:00:00.000Z",
        "slots": 10,
        "noOfTickets": 10,
        "itemIDs": [
          "string"
        ],
        "isDefault": true,
        "status": "active",
        "archived": true
      }
    ],
    "items": [
      {
        "id": "a1b2c3d4e5",
        "type": "string",
        "title": "Design masterclass",
        "description": "A hands-on class covering the basics.",
        "image": "string",
        "duration": 30,
        "isAddon": true,
        "parentId": "a1b2c3d4e5",
        "price": {
          "amount": 5000,
          "currency": "USD"
        }
      }
    ],
    "checkoutFields": [
      {
        "id": "a1b2c3d4e5",
        "label": "string",
        "type": "string",
        "required": true,
        "options": [
          "string"
        ]
      }
    ]
  }
}

List a product's customers

GET/products/{id}/customers
customers:read

Lists the product's active customers (purchasers), newest first.

Path parameters

id

string

required

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/products/a1b2c3d4e5/customers" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "membershipId": "a1b2c3d4e5",
        "name": "Ada Lovelace",
        "email": "ada@example.com",
        "phone": "+2348012345678",
        "hubID": "a1b2c3d4e5",
        "status": "active",
        "plan": "string",
        "joinedAt": "2026-07-06T10:00:00.000Z"
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Import customers to a product

POST/products/{id}/customers/import
customers:write

Bulk-imports customers into the product. Send `records` as an array of objects keyed by field id (see `checkoutFields` on the product); `fullName` and `email` are required, e.g. `[{ "fullName": "Ada Lovelace", "email": "ada@example.com" }]`. Queues the import and returns how many records were accepted.

Path parameters

id

string

required

Body parameters

records

array of object

required

plan

string

Request

curl -X POST "https://nestuge.com/api/v1/products/a1b2c3d4e5/customers/import" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      {}
    ]
  }'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "queued": true,
    "count": 10
  }
}

Transactions


List transactions

GET/transactions
transactions:read

Lists the brand's transactions, newest first.

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/transactions" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "txref": "string",
        "type": "string",
        "status": "active",
        "amount": 5000,
        "currency": "USD",
        "customer": {
          "name": "Ada Lovelace",
          "email": "ada@example.com"
        },
        "createdAt": "2026-07-06T10:00:00.000Z",
        "resourceID": "a1b2c3d4e5"
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Get a transaction

GET/transactions/{id}
transactions:read

Returns a single transaction by its reference.

Path parameters

id

string

required

Request

curl "https://nestuge.com/api/v1/transactions/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "txref": "string",
    "type": "string",
    "status": "active",
    "amount": 5000,
    "currency": "USD",
    "customer": {
      "name": "Ada Lovelace",
      "email": "ada@example.com"
    },
    "createdAt": "2026-07-06T10:00:00.000Z",
    "resourceID": "a1b2c3d4e5"
  }
}

Webhooks


List webhook endpoints

GET/webhooks
webhooks:write

Lists the brand's webhook endpoints.

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/webhooks" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "id": "a1b2c3d4e5",
        "url": "https://example.com/webhooks/nestuge",
        "events": [
          "transaction.succeeded"
        ],
        "status": "active",
        "description": "A hands-on class covering the basics.",
        "createdAt": "2026-07-06T10:00:00.000Z",
        "updatedAt": "2026-07-06T10:00:00.000Z"
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Create a webhook endpoint

POST/webhooks
webhooks:write

Registers an endpoint URL. The signing secret is returned once in this response and never again.

Body parameters

url

string

required

events

array of enum

required

transaction.succeededtransaction.failedpayout.settledsubscription.renewedsubscription.expiredsubscription.completedmember.joinedmember.removed

description

string

Request

curl -X POST "https://nestuge.com/api/v1/webhooks" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/nestuge",
    "events": [
      "transaction.succeeded"
    ]
  }'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "url": "https://example.com/webhooks/nestuge",
    "events": [
      "transaction.succeeded"
    ],
    "status": "active",
    "description": "A hands-on class covering the basics.",
    "createdAt": "2026-07-06T10:00:00.000Z",
    "updatedAt": "2026-07-06T10:00:00.000Z",
    "signingSecret": "string"
  }
}

Get a webhook endpoint

GET/webhooks/{id}
webhooks:write

Path parameters

id

string

required

Request

curl "https://nestuge.com/api/v1/webhooks/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "url": "https://example.com/webhooks/nestuge",
    "events": [
      "transaction.succeeded"
    ],
    "status": "active",
    "description": "A hands-on class covering the basics.",
    "createdAt": "2026-07-06T10:00:00.000Z",
    "updatedAt": "2026-07-06T10:00:00.000Z"
  }
}

Update a webhook endpoint

PATCH/webhooks/{id}
webhooks:write

Path parameters

id

string

required

Body parameters

url

string

events

array of enum

transaction.succeededtransaction.failedpayout.settledsubscription.renewedsubscription.expiredsubscription.completedmember.joinedmember.removed

status

enum

activedisabled

description

string

Request

curl -X PATCH "https://nestuge.com/api/v1/webhooks/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "url": "https://example.com/webhooks/nestuge",
    "events": [
      "transaction.succeeded"
    ],
    "status": "active",
    "description": "A hands-on class covering the basics.",
    "createdAt": "2026-07-06T10:00:00.000Z",
    "updatedAt": "2026-07-06T10:00:00.000Z"
  }
}

Delete a webhook endpoint

DELETE/webhooks/{id}
webhooks:write

Path parameters

id

string

required

Request

curl -X DELETE "https://nestuge.com/api/v1/webhooks/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "deleted": false
  }
}

Send a test webhook event

POST/webhooks/test
webhooks:write

Synthesizes a sample event and delivers it through the real signed/retried/logged pipeline as a sample delivery.

Body parameters

eventType

enum

required

transaction.succeededtransaction.failedpayout.settledsubscription.renewedsubscription.expiredsubscription.completedmember.joinedmember.removed

endpointID

string

Request

curl -X POST "https://nestuge.com/api/v1/webhooks/test" \
  -H "x-nestuge-api: nk_test_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "eventType": "transaction.succeeded"
  }'

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "created": 10
  }
}

List webhook deliveries

GET/webhooks/deliveries
webhooks:write

Query parameters

limit

string

cursor

string

Request

curl "https://nestuge.com/api/v1/webhooks/deliveries" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "items": [
      {
        "id": "a1b2c3d4e5",
        "endpointID": "a1b2c3d4e5",
        "eventType": "transaction.succeeded",
        "resourceType": "transaction",
        "resourceID": "a1b2c3d4e5",
        "status": "pending",
        "attempts": 10,
        "responseCode": 10,
        "mode": "live",
        "createdAt": "2026-07-06T10:00:00.000Z",
        "deliveredAt": "2026-07-06T10:00:00.000Z"
      }
    ],
    "hasMore": true,
    "nextCursor": "a1b2c3d4e5"
  }
}

Get a webhook delivery

GET/webhooks/deliveries/{id}
webhooks:write

Path parameters

id

string

required

Request

curl "https://nestuge.com/api/v1/webhooks/deliveries/a1b2c3d4e5" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "endpointID": "a1b2c3d4e5",
    "eventType": "transaction.succeeded",
    "resourceType": "transaction",
    "resourceID": "a1b2c3d4e5",
    "status": "pending",
    "attempts": 10,
    "responseCode": 10,
    "mode": "live",
    "createdAt": "2026-07-06T10:00:00.000Z",
    "deliveredAt": "2026-07-06T10:00:00.000Z"
  }
}

Resend a webhook delivery

POST/webhooks/deliveries/{id}/resend
webhooks:write

Path parameters

id

string

required

Request

curl -X POST "https://nestuge.com/api/v1/webhooks/deliveries/a1b2c3d4e5/resend" \
  -H "x-nestuge-api: nk_test_your_key"

Response

{
  "status": "success",
  "message": "OK",
  "data": {
    "id": "a1b2c3d4e5",
    "endpointID": "a1b2c3d4e5",
    "eventType": "transaction.succeeded",
    "resourceType": "transaction",
    "resourceID": "a1b2c3d4e5",
    "status": "pending",
    "attempts": 10,
    "responseCode": 10,
    "mode": "live",
    "createdAt": "2026-07-06T10:00:00.000Z",
    "deliveredAt": "2026-07-06T10:00:00.000Z"
  }
}

Products


© Nestuge Inc.