Loading...
Loading...
NABBA Developers
Your band's website or membership database can talk to NABBA directly: read and update the band's record on nabba.org, keep the band's roster here in step with your own, and read where your Championships registration stands. One key per integration, created by a band admin, with only the permissions it needs.
Send the key on every request:
Authorization: Bearer nabba_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAll requests are HTTPS JSON. Limit: 600 requests an hour per key. Errors come back as { "error": { "code", "message" } } with 400, 401, 403, 404 or 429.
| band:read | The band's profile, NABBA membership standing, managers, and Championships history. |
| band:write | Update website, bio, director, location and social links. Name and slug are set by NABBA. |
| roster:read | Everyone on the band's nabba.org roster, with whether each person's NABBA membership is valid on a given date. |
| roster:write | Add, update and remove people on the band's roster. Band admins are never removed by the API. |
| entries:read | The band's Championships entries with the eight-step registration checklist, pieces, late fee and roster state. |
/api/v1/bandband:readThe band's record, membership standing and managers.
curl https://nabba.org/api/v1/band \
-H "Authorization: Bearer $NABBA_KEY"
{
"band": { "id": "…", "name": "Dublin Silver Band", "slug": "dublin-silver-band",
"url": "https://nabba.org/bands/dublin-silver-band", "website": "…", "director": "…", "bio": "…" },
"membership": { "status": "ACTIVE", "expiresAt": "2027-03-31T…", "current": true,
"renewUrl": "https://nabba.org/join/band?band=…" },
"managers": [ { "name": "Tim Jameson", "email": "…", "primaryContact": true } ],
"rosterCount": 34
}/api/v1/bandband:writeUpdate the band's profile. Send only the fields you want to change; null clears one.
curl -X PATCH https://nabba.org/api/v1/band \
-H "Authorization: Bearer $NABBA_KEY" -H "Content-Type: application/json" \
-d '{ "website": "https://dublinsilverband.org",
"director": "Tim Jameson",
"bio": "Founded in 2013…",
"socialLinks": { "facebook": "https://facebook.com/dublinsilverband" } }'/api/v1/band/rosterroster:readEveryone verified on the band's roster, with membership validity. ?on=2027-04-10 checks validity on the contest day; ?include=left adds people who have left.
curl "https://nabba.org/api/v1/band/roster?on=2027-04-10" \
-H "Authorization: Bearer $NABBA_KEY"
{
"validOn": "2027-04-10", "count": 34,
"members": [
{ "email": "…", "firstName": "Ann", "lastName": "Player", "roles": ["PLAYER"], "bandAdmin": false,
"rosterStatus": "verified", "ref": "crm-1182",
"membership": { "type": "INDIVIDUAL", "status": "ACTIVE", "expiresAt": "2027-12-31T…", "valid": true } }
]
}/api/v1/band/rosterroster:writeSync the roster from your list. merge (default) adds anyone missing and updates roles; nobody is removed. replace also marks people not in your list as having left. Roles: MUSIC_DIRECTOR, ASSISTANT_DIRECTOR, SECTION_LEADER, PLAYER, MANAGER, LIBRARIAN, BOARD_MEMBER. ref is your own id, echoed back on reads.
Someone without a NABBA account is added to the roster with a placeholder record and no membership; they still need to join NABBA themselves to be a member. Band admins and the band's own login are never removed by a sync, so a bad run cannot lock the band out.
curl -X PUT https://nabba.org/api/v1/band/roster \
-H "Authorization: Bearer $NABBA_KEY" -H "Content-Type: application/json" \
-d '{ "mode": "replace",
"members": [
{ "email": "tim@example.org", "firstName": "Tim", "lastName": "Jameson", "roles": ["MUSIC_DIRECTOR"], "ref": "1" },
{ "email": "ann@example.org", "firstName": "Ann", "lastName": "Player", "roles": ["PLAYER"], "ref": "2" }
] }'
{ "ok": true, "mode": "replace", "received": 2, "added": 1, "updated": 0, "unchanged": 1,
"removed": 3, "createdMembers": 1, "rejected": [] }/api/v1/band/entriesentries:readThe band's Championships entries, newest first, each with the registration checklist exactly as the band sees it on nabba.org: step, state (todo, doing, done, late, locked), due date and detail. Useful for a “Championships status” box on the band's own members page.
curl https://nabba.org/api/v1/band/entries -H "Authorization: Bearer $NABBA_KEY"
{ "entries": [ { "event": { "name": "Championships 2027", "startDate": "2027-04-08T…" },
"status": "PAID", "section": "Second",
"checklist": [ { "step": 1, "key": "membership", "title": "Band membership", "state": "done", "due": "…", "detail": "Current through …" },
{ "step": 4, "key": "scores", "state": "doing", "detail": "1/2 scores in. Due Jan 15, 2027." } ],
"roster": { "submittedAt": null, "verifiedAt": null, "performing": 29, "problems": [] },
"manageUrl": "https://nabba.org/portal/bands/dublin-silver-band/register" } ] }/api/v1/band/historyband:readEvery Championships the band has played, with section, test piece, own-choice pieces and placings.
// Node 18+. Runs after your membership database updates.
const members = await db.query("select email, first_name, last_name, section_role, id from active_members");
const res = await fetch("https://nabba.org/api/v1/band/roster", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.NABBA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
mode: "replace",
members: members.map((m) => ({ email: m.email, firstName: m.first_name, lastName: m.last_name,
roles: [m.section_role === "MD" ? "MUSIC_DIRECTOR" : "PLAYER"], ref: String(m.id) })),
}),
});
console.log(await res.json()); // { ok: true, added, updated, removed, rejected: [...] }A machine-readable description is at /api/v1/openapi.json.