TheBlipBank view

Partner API

Connect your app to TheBlip. Send us what a student did, and we return points, levels and an embeddable rewards widget. You never need to send raw transactions or personal details.

Quick start

  1. Ask your TheBlip admin for an API key (Console, then Integration).
  2. Send an event when a student does something worth rewarding.
  3. Show the result with the embeddable widget, or read it back from the API.
curl -X POST https://your-site.example.com/api/v1/events \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"studentId":"user-42","type":"autopay_enabled"}'
{
  "awarded": 150,
  "questId": "autopay",
  "blocked": false,
  "message": "Quest completed: Set up autopay",
  "student": { "id": "user-42", "points": 150, "level": { "index": 1, "name": "Rookie" } }
}

Authentication

Send your key on every request as a bearer token. Keys start with blip_live_. Keep them on your server and never put one in a web page or a mobile app. We store only a fingerprint of each key, so a lost key cannot be recovered. Create a new one and revoke the old one.

Authorization: Bearer blip_live_xxxxxxxxxxxxxxxx

Limits: 300 requests a minute per key, 600 a minute per address, and 20 invalid keys in 10 minutes before an address is paused.

POST/api/v1/events

Tell us a student did something. studentId is your own id for the student, 1 to 64 characters. We recommend an opaque id rather than an email or name. type must be one of your program's event names (see the quests endpoint). A student earns each quest once. Sending it again returns awarded: 0.

{ "studentId": "user-42", "type": "payment_on_time" }

If the student is in recovery mode after a scam, quest events are paused and the response says blocked: true. If your program has used its points budget, no points are given and the message says so.

GET/api/v1/students/:id

Read a student's points, level and quest progress. Returns 404 for a student we have not seen yet.

{
  "id": "user-42", "points": 350, "xp": 350,
  "level": { "index": 2, "name": "Watcher", "progress": 33 },
  "locked": false,
  "quests": [ { "id": "autopay", "title": "Set up autopay", "event": "autopay_enabled", "points": 150, "done": true } ]
}

GET/api/v1/quests

Your program's quests, including any custom ones your admin created, with the event name that completes each.

GET/api/v1/stats?days=14

Program totals, a funnel from enrolled to level 3, a daily series, quest counts, and the most common scam signals students reported. Between 7 and 90 days. Simulated demo students are never included.

POST/api/v1/embed-token

Create a short-lived, read-only token for one student, to show the rewards widget in your app. Tokens last 1 hour by default (60 seconds to 24 hours with ttlSeconds). Mint a fresh one each time you render the page, on your server.

curl -X POST https://your-site.example.com/api/v1/embed-token \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"studentId":"user-42","ttlSeconds":3600}'

The response includes a url and a ready-made script tag.

Embed the widget

Paste this where the widget should appear. It creates a responsive frame that resizes itself and uses your program's name and color.

<script src="https://your-site.example.com/embed.js" data-token="TOKEN_FROM_YOUR_SERVER"></script>

Or use the frame yourself: <iframe src="https://your-site.example.com/embed?token=TOKEN" style="width:100%;border:0"></iframe>. The token only allows reading one student's progress. It cannot award points.

Webhooks

We call your address when a student earns points, so you can update your own records or send a notification. Set the address and copy the signing secret in the Console. Addresses must be public https:// URLs.

POST https://your-server.example.com/blip-webhook
X-Blip-Timestamp: 1790000000
X-Blip-Signature: sha256=9c1f...
Content-Type: application/json

{ "type": "points.awarded", "student": "user-42", "points": 150,
  "reason": "quest", "quest": "autopay", "totalPoints": 150, "ts": "2026-09-19T14:03:11.000Z" }

The signature is an HMAC-SHA256 of timestamp + "." + rawBody using your secret. Always verify it, and reject requests whose timestamp is more than a few minutes old.

// Node.js
import crypto from 'crypto';
function valid(secret, ts, rawBody, header) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
  return header.length === expected.length && crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
# Python
import hmac, hashlib
def valid(secret, ts, raw_body, header):
    expected = "sha256=" + hmac.new(secret.encode(), (ts + "." + raw_body).encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)

Answer with any 2xx status within 5 seconds. We do not retry yet, and we do not follow redirects. Recent deliveries and errors are listed in the Console.

Errors

StatusCodeMeaning
400invalid_json, invalid_student_id, unknown_eventThe request is malformed. unknown_event lists the valid events.
401missing_key, invalid_keyNo key, or a key that is wrong or revoked.
404not_foundStudent not seen yet.
429rate_limitedSlow down and retry.
503capacityThe program is full. Contact your admin.
{ "error": { "code": "unknown_event", "message": "That event type is not recognized for your program.", "validEvents": ["autopay_enabled", "..."] } }

What we store

Your student id, the events you send, and the points and level that result. No names, emails or account numbers are needed. Points are earned only from behavior you report. There are no points for opening accounts or spending.

Try it without writing code: open the Console, go to Integration, create a key and mint a widget.