API v1 · REST · JSON

The Tipping Jar Developer Platform

A fast, secure REST API to integrate tipping flows into any product. Accept tips in ZAR, manage creator jars, issue payouts, and react to events with signed webhooks.

< 200ms

Median latency

99.99%

API uptime

ZAR

Default currency

Free

Sandbox included

Authentication

API Keys & Bearer Tokens

The Tipping Jar uses JWT Bearer tokens for authentication. Obtain a token pair by posting credentials to the token endpoint. Include your access token in every authenticated request via the Authorization header.

01

Register

Create an account at tippingjar.co.za or via POST /api/users/register/

02

Get Token

POST credentials to /api/auth/token/ — receive an access + refresh token pair

03

Authenticate

Pass the access token in the Authorization: Bearer <token> header on every request

04

Refresh

Use your refresh token to obtain a new access token before it expires (60 min TTL)

API Keys

Sign in to generate and manage your API keys.

tj_live_sk_v1_••••••••••••••••••••
# Step 1 — Obtain token pair
curl -X POST https://api.tippingjar.co.za/v1/auth/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "janedoe", "password": "SuperSecret123"}'

# Response:
# { "access": "eyJ...", "refresh": "eyJ...", "user": { ... } }

# Step 2 — Use the access token
curl https://api.tippingjar.co.za/v1/creators/me/ \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Step 3 — Refresh when expired (60 min TTL)
curl -X POST https://api.tippingjar.co.za/v1/auth/token/refresh/ \
  -H "Content-Type: application/json" \
  -d '{"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}'

Access token lifetime

Access tokens expire after 60 minutes. Refresh tokens last 7 days. Your application should detect 401 Unauthorized responses and call /api/auth/token/refresh/ automatically to obtain a new access token.

Quick Start

Send your first tip in 5 minutes

Authenticate, then create a tip payment with a single API call.

# 1. Get your access token
curl -X POST https://api.tippingjar.co.za/v1/auth/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "janedoe", "password": "SuperSecret123"}'

# 2. Send a tip (sandbox — no Stripe key required)
curl -X POST https://api.tippingjar.co.za/v1/tips/initiate/ \
  -H "Content-Type: application/json" \
  -d '{
    "creator_slug": "jane-creates",
    "amount": 50.00,
    "message": "Love your work!",
    "tipper_name": "BigFan"
  }'

# Response (sandbox)
{
  "success": true,
  "tip_id": 123,
  "amount": "50.00",
  "creator_name": "Jane Creates"
}

API Reference

Complete endpoint reference

Base URL https://api.tippingjar.co.za/v1

bi-shield-lock-fill

Authentication

Obtain and refresh JWT access tokens.

bi-person-fill

Creators

Manage creator profiles and retrieve public data.

bi-piggy-bank-fill

Jars

Campaign-specific tip jars with optional fundraising goals.

bi-cash-coin

Tips

Initiate tip payments and retrieve tip history.

Error Codes

Error handling

All errors follow a consistent JSON structure with a detail field.

400

Bad Request

Invalid request body or missing required fields.

401

Unauthorized

Missing or invalid Bearer token. Re-authenticate.

403

Forbidden

Authenticated but not allowed to perform this action.

404

Not Found

Resource does not exist or has been deleted.

405

Method Not Allowed

HTTP method not supported on this endpoint.

422

Validation Error

Request body failed field-level validation. See errors object.

429

Too Many Requests

Rate limit exceeded. Check Retry-After header.

500

Internal Server Error

Unexpected server error. Contact support@tippingjar.co.za.

Error response shape
{
  "detail": "Authentication credentials were not provided.",

  // Validation errors (HTTP 422) include field-level details:
  "errors": {
    "amount": ["Ensure this value is greater than or equal to 1."],
    "creator_slug": ["This field is required."]
  },

  // Rate limit errors (HTTP 429) include:
  "retry_after": 42   // seconds until limit resets
}

Rate Limits

Rate limiting

Limits apply per IP for public endpoints and per access token for authenticated ones.

60 req / min

Unauthenticated

Per IP address

300 req / min

Authenticated

Per user token

30 req / hour

Tip creation

Per IP / user

20 req / hour

Token refresh

Per user

1 000 req / min

Platform API

Per platform key

Rate limit headers

Every response includes:
  X-RateLimit-Limit      — your limit for this window
  X-RateLimit-Remaining  — requests remaining
  X-RateLimit-Reset      — Unix timestamp the window resets
  Retry-After            — seconds to wait (only on 429 responses)

Webhooks

Real-time event notifications

Register an HTTPS endpoint in your dashboard. The Tipping Jar will POST signed payloads to your URL on every event. Verify signatures using HMAC-SHA256 with your webhook secret.

tip.completedFires immediately when a tip payment succeeds.
tip.failedFires when a Stripe payment attempt fails.
tip.refundedFires when a tip is refunded to the tipper.
jar.createdA creator published a new jar.
jar.goal_reachedA jar's total_raised has met or exceeded goal.
creator.createdA new creator profile was registered.
payout.initiatedStripe has initiated a bank transfer.
payout.completedPayout has arrived in the creator's account.
Payload example
{
  "id": "evt_01HXYZ3Qf8TzKYlo2C1Bx",
  "type": "tip.completed",
  "created": 1740481200,
  "livemode": true,
  "data": {
    "tip": {
      "id": 123,
      "amount": "50.00",
      "currency": "zar",
      "message": "Love your work!",
      "status": "completed",
      "jar": null,
      "creator": {
        "slug": "jane-creates",
        "display_name": "Jane Creates"
      },
      "tipper_name": "BigFan",
      "created_at": "2026-02-21T08:20:00Z"
    }
  }
}
Signature verification (Node.js)
import crypto from "crypto";

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody, "utf8")
    .digest("hex");

  // Constant-time comparison to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(signature, "hex"),
  );
}

// Express example
app.post("/webhook/tippingjar", express.raw({ type: "*/*" }), (req, res) => {
  const sig = req.headers["tj-signature"];
  if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send("Invalid signature");
  }
  const event = JSON.parse(req.body);
  if (event.type === "tip.completed") {
    console.log("Tip received:", event.data.tip.amount, "ZAR");
  }
  res.sendStatus(200);
});

Signature verification

Every webhook request includes a TJ-Signature header. Compute
HMAC-SHA256(payload_body, your_webhook_secret) and compare it to
the header value. Reject any requests where they don't match.

SDKs

Official client libraries

All SDKs are open source and MIT-licensed.

Python

Python 3.8+

pip install tippingjar

v1.4.0

Node.js

TypeScript ready

npm install @tippingjar/sdk

v1.6.2

Dart / Flutter

Null-safe

tippingjar: ^1.2.0

v1.2.0

Go

Go 1.21+

go get github.com/tippingjar/go

v1.1.0

Platform API

Embed tipping in your app

The Platform API lets third-party applications integrate The Tipping Jar tipping without requiring end-users to create accounts directly. Authenticate requests using the X-Platform-Key header. Each platform has its own isolated user pool and rate limit envelope.

Key format

X-Platform-Key: tj_platform_sk_v1_<32-char-hex>

Platform keys are generated once on approval and hashed server-side. Store them as environment secrets — they cannot be retrieved again.

Endpoints

GET/api/platform/me/Get platform info + key prefix
GET/api/platform/creators/List active creators (public)
GET/api/platform/users/List end-users on this platform
POST/api/platform/users/Register or update an end-user
POST/api/platform/tips/Initiate a tip as a platform user
# Authenticate with your platform key
curl -H "X-Platform-Key: tj_platform_sk_v1_..." \
  https://api.tippingjar.co.za/api/platform/creators/

Partner Program

Become a Tipping Jar partner

The Partner Program gives SA-registered businesses access to the Platform API and dedicated support. Applications are reviewed within 48 business hours.

SA-registered business

Your company must be registered with CIPC (Pty Ltd, CC, or NPC).

Company documents

CIPC certificate, VAT letter, director ID, and bank confirmation letter.

48 h review

Our compliance team reviews every application within two business days.

Dedicated support

Approved partners receive a dedicated integration engineer contact.

Ready to apply?

Complete a short multi-step form with your business details.

Apply for Platform API access →

Start building today

Free sandbox · No credit card · ZAR currency ready

Get your API key