we bring it back

Developers

Business API

Push found items from your desk software, keep their status in sync, and get webhooks the moment a visitor's lost report matches or someone claims an item.

1. Get a key

Your organization's owner/admin creates one under Organization → Developers. Keys belong to one organization.

2. Push items

POST items with your own externalId. Retries are safe — the same externalId never creates duplicates.

3. Listen

Register a webhook to hear about matches, claims and status changes in real time.

Quick start

Send your key as a bearer token. Location defaults to your organization's center if you leave it out.

curl -X POST https://dev.webringitback.com/api/v1/items \
  -H "Authorization: Bearer wbib_live_XXXXXXXX_..." \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "DESK-2026-00042",
    "title": "Black leather wallet",
    "category": "wallet",
    "color": "Black",
    "address": "Food court, Level 2",
    "storageLocation": "Desk A, drawer 2",
    "hiddenDetails": "Library card inside"
  }'

Attach a photo — upload a file, or give us a public image URL:

curl -X POST https://dev.webringitback.com/api/v1/items/ITEM_ID/photos -H "Authorization: Bearer $KEY" -F "file=@wallet.jpg"

curl -X POST https://dev.webringitback.com/api/v1/items/ITEM_ID/photos -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" -d '{"url": "https://cdn.example.com/wallet.jpg"}'

Mark it returned when the owner collects it:

curl -X PATCH https://dev.webringitback.com/api/v1/items/ITEM_ID -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" -d '{"status": "RETURNED"}'

Scopes

Rate limits & errors

Each key has a per-minute limit and an optional daily quota, set by your organization admin. Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit you get 429 with a Retry-After header — wait that many seconds and retry.

HTTP/1.1 429 Too Many Requests
Retry-After: 18

{ "error": { "code": "rate_limited", "message": "Too many requests. Slow down." } }

Error codes: unauthorized, key_revoked, key_expired (401) · insufficient_scope, api_disabled (403) · not_found (404) · conflict (409) · validation_error (422) · rate_limited (429).

Webhooks

We POST JSON to your HTTPS endpoint and retry failures with exponential backoff (up to 8 attempts). Endpoints that fail 20 times in a row are paused automatically. Events:

Verify every request: X-WBIB-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, t + "." + rawBody). Reject timestamps older than 5 minutes and de-duplicate on the event id.

// Node.js (Express) — use the raw body, not parsed JSON
import crypto from "node:crypto";

app.post("/webhooks/lost-found", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("X-WBIB-Signature") ?? "";
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", process.env.WBIB_WEBHOOK_SECRET)
    .update(`${t}.${req.body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  if (!fresh || !v1 || !crypto.timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex"))) {
    return res.sendStatus(400);
  }
  const event = JSON.parse(req.body);
  // event.event === "match.created" | "claim.created" | ...
  res.sendStatus(200);
});
# Python (Flask)
import hmac, hashlib, time, os
from flask import request, abort

@app.post("/webhooks/lost-found")
def wbib_webhook():
    parts = dict(p.split("=", 1) for p in request.headers.get("X-WBIB-Signature", "").split(","))
    body = request.get_data()
    expected = hmac.new(os.environ["WBIB_WEBHOOK_SECRET"].encode(), f"{parts.get('t')}.".encode() + body, hashlib.sha256).hexdigest()
    if abs(time.time() - int(parts.get("t", 0))) > 300 or not hmac.compare_digest(expected, parts.get("v1", "")):
        abort(400)
    event = request.get_json()
    return "", 200

Need higher limits? Contact support@webringitback.com. Manage keys in your organization → Developers.