Reference
Connect events from your platform, add game sessions and publish them. Every call acts as one Neegma host, with the access token they gave your app. The same contract is available as an OpenAPI spec for Postman or a client generator.
https://tryneegma.com/api/v1Send the host's OAuth access token on every request. See how the host connects.
Authorization: Bearer <access token>
Content-Type: application/jsonErrors share one shape. code is stable for your code to check; message is fine to show the host.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or wrong. message names it. |
| 400 | invalid_event | The event cannot be created, such as a title under 2 characters. |
| 400 | invalid_source | source is not 2 to 32 lowercase letters, digits or hyphens. |
| 400 | invalid_external_id | external_id is empty, too long, or has a space or slash. |
| 400 | cannot_publish | The event has nothing in it to publish yet. Add a session. |
| 401 | invalid_token | Refresh the access token, or ask the host to connect again. |
| 403 | limit_reached | The host's plan limit is reached. Show message and upgrade_url. |
| 403 | upgrade_required | The host's plan does not include this, such as private sessions. |
| 403 | template_not_allowed | The host cannot use that template. |
| 403 | event_pass_not_allowed | event_pass needs a partner agreement. Contact us to sell Neegma events. |
| 404 | not_found | The event does not exist, or belongs to another host. |
| 409 | event_finished | The event has finished, so nothing more can be added. |
| 429 | rate_limited | Too many requests. Wait a minute, then try again. |
| 500 | server_error | Something went wrong on Neegma's side. Try again shortly. |
| 503 | temporarily_unavailable | Neegma could not check the account just now. Try again. |
/api/v1/connected-events/{source}/{external_id}Creates the Neegma event for one of your events the first time (201), and updates it on every later call (200). Safe to retry: it never creates a second event. Send your own event object with a mapping, or send Neegma's field names.
sourcestringrequiredA short name for your platform: 2 to 32 lowercase letters, digits or hyphens.
external_idstringrequiredThe event's ID on your platform. Up to 128 characters, no spaces or slashes.
datamaprequiredYour event, exactly as your platform stores it.
mappingobjectrequiredWhich of your fields holds each piece Neegma needs. Paths are dot paths into data.
titlestringrequiredmapping.title
Field holding the event's name.
starts_atstringmapping.starts_at
Field holding the start, as ISO 8601.
timezonestringmapping.timezone
Field holding the IANA timezone.
urlstringmapping.url
Field holding your event page's URL.
privacystring or objectmapping.privacy
Field holding public or private, or a translation of your own values.
fieldstringrequiredmapping.privacy.field
The field in your object that holds the value.
valuesmapmapping.privacy.values
Your value on the left, Neegma's on the right.
defaultstringmapping.privacy.default
Used for any value not listed in values.
One of: public, private
attendeesobjectmapping.attendees
Where the guest list is, and what each guest's fields are.
liststringrequiredmapping.attendees.list
Field holding the array of guests.
namestring or array of stringrequiredmapping.attendees.name
Field in each guest holding the name, or up to 3 joined with a space.
emailstringmapping.attendees.email
Field in each guest holding the email. Accepted, not stored yet.
external_idstringmapping.attendees.external_id
Field in each guest holding your ID for them.
statusstring or objectmapping.attendees.status
Field holding going, invited or not_going, or a translation.
event_passobjectFor partners who sell Neegma events: the paid event pass this event uses. A pass moves or comes off only until guests join. Apps without a partner agreement get event_pass_not_allowed.
paidbooleanrequiredevent_pass.paid
This event is paid for.
One of: true
plan_codestringrequiredevent_pass.plan_code
The pass bought: party_pass_50, _100, _150 or _200, by the guests it allows.
One of: party_pass_50, party_pass_100, party_pass_150, party_pass_200
referencestringrequiredevent_pass.reference
Your ID for the pass, such as your order line. Send it for another event to move it.
paidbooleanrequiredevent_pass.paid
Takes your pass off this event.
One of: false
titlestringrequiredThe event's name. 2 to 50 characters; longer names are cut.
starts_atstring (date-time) or nullISO 8601 start. Leave it out to keep the current time.
timezonestring or nullIANA timezone, such as Europe/London.
urlstring or nullYour event page.
privacystringprivate puts a join PIN on every session added to the event.
One of: public, private
attendeesarray of objectThe full guest list. Replaces the one Neegma holds; leave it out to keep it.
namestringrequiredattendees[].name
The guest's name. Cut to 80 characters.
emailstring or nullattendees[].email
Optional. Accepted, but not stored yet: nothing in Neegma uses it.
external_idstring or number or nullattendees[].external_id
Your ID for the guest. Stops the same guest being added twice.
statusstringattendees[].status
Defaults to going.
One of: going, invited, not_going
event_passobjectFor partners who sell Neegma events: the paid event pass this event uses. A pass moves or comes off only until guests join. Apps without a partner agreement get event_pass_not_allowed.
paidbooleanrequiredevent_pass.paid
This event is paid for.
One of: true
plan_codestringrequiredevent_pass.plan_code
The pass bought: party_pass_50, _100, _150 or _200, by the guests it allows.
One of: party_pass_50, party_pass_100, party_pass_150, party_pass_200
referencestringrequiredevent_pass.reference
Your ID for the pass, such as your order line. Send it for another event to move it.
paidbooleanrequiredevent_pass.paid
Takes your pass off this event.
One of: false
The connected event. 200 on an update.
createdbooleanrequiredTrue the first time, when the event was created.
eventobjectrequiredA Neegma event.
idintegerrequiredevent.id
Neegma's ID for the event. Use it in /events/{id}.
titlestringrequiredevent.title
statusstringrequiredevent.status
One of: draft, scheduled, ready, active, completed
starts_atstring or nullrequiredevent.starts_at
ISO 8601, or null to play now.
timezonestring or nullrequiredevent.timezone
privacystringrequiredevent.privacy
One of: public, private
connectionobject or nullrequiredevent.connection
The platform event this one is connected to, if any.
attendeesobjectrequiredevent.attendees
How many guests the event holds, by status.
unpublished_changesarray of stringrequiredevent.unpublished_changes
What guests cannot see yet. Publish when it is not empty.
session_countintegerrequiredevent.session_count
manage_urlstringrequiredevent.manage_url
The event in the host's Neegma dashboard.
attendee_urlstringrequiredevent.attendee_url
The one link to share with guests.
host_urlstringrequiredevent.host_url
Where the host opens the event on the day.
sessionsarray of objectrequiredevent.sessions
event_passobjectOnly when you sent event_pass. If a pass could not move, a warning says why.
passobject or nullrequiredevent_pass.pass
The pass now on the event, or null when it has none.
releasedstring or nullrequiredevent_pass.released
A pass that came off this event, free to use on another one.
warningsarray of stringrequiredWhat Neegma changed or could not keep, without failing the call. Show them to the host.
invalid_request, invalid_event, invalid_source, invalid_external_id, invalid_token, event_pass_not_allowed, rate_limited
curl -X PUT https://tryneegma.com/api/v1/connected-events/eventful/evt-123 \
-H "Authorization: Bearer $NEEGMA_TOKEN" \
-H "Content-Type: application/json" \
-d @body.json{
"data": {
"id": "evt-123",
"name": "Friday team social",
"start_at": "2026-11-06T16:00:00Z",
"tz": "Europe/London",
"page": "https://eventful.example/e/friday-social",
"visibility": "members-only",
"guests": [
{
"id": "g1",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"rsvp": "yes"
},
{
"id": "g2",
"first_name": "Alan",
"last_name": "Turing",
"email": "alan@example.com",
"rsvp": "maybe"
}
]
},
"mapping": {
"title": "name",
"starts_at": "start_at",
"timezone": "tz",
"url": "page",
"privacy": {
"field": "visibility",
"values": {
"public": "public",
"members-only": "private"
},
"default": "public"
},
"attendees": {
"list": "guests",
"name": [
"first_name",
"last_name"
],
"email": "email",
"external_id": "id",
"status": {
"field": "rsvp",
"values": {
"yes": "going",
"maybe": "invited",
"no": "not_going"
},
"default": "invited"
}
}
}
}{
"created": true,
"event": {
"id": 4182,
"title": "Friday team social",
"status": "draft",
"starts_at": "2026-11-06T16:00:00.000Z",
"timezone": "Europe/London",
"privacy": "private",
"connection": {
"source": "eventful",
"external_id": "evt-123",
"url": "https://eventful.example/e/friday-social"
},
"attendees": {
"going": 1,
"invited": 1,
"not_going": 0,
"total": 2
},
"unpublished_changes": [],
"session_count": 0,
"manage_url": "https://tryneegma.com/dashboard/events/4182",
"attendee_url": "https://tryneegma.com/event/k3x9a7mq2b4z",
"host_url": "https://tryneegma.com/event/k3x9a7mq2b4z/host",
"sessions": []
},
"warnings": []
}/api/v1/connected-events/{source}/{external_id}The Neegma event connected to one of your events.
sourcestringrequiredA short name for your platform: 2 to 32 lowercase letters, digits or hyphens.
external_idstringrequiredThe event's ID on your platform. Up to 128 characters, no spaces or slashes.
The event.
eventobjectrequiredA Neegma event.
idintegerrequiredevent.id
Neegma's ID for the event. Use it in /events/{id}.
titlestringrequiredevent.title
statusstringrequiredevent.status
One of: draft, scheduled, ready, active, completed
starts_atstring or nullrequiredevent.starts_at
ISO 8601, or null to play now.
timezonestring or nullrequiredevent.timezone
privacystringrequiredevent.privacy
One of: public, private
connectionobject or nullrequiredevent.connection
The platform event this one is connected to, if any.
attendeesobjectrequiredevent.attendees
How many guests the event holds, by status.
unpublished_changesarray of stringrequiredevent.unpublished_changes
What guests cannot see yet. Publish when it is not empty.
session_countintegerrequiredevent.session_count
manage_urlstringrequiredevent.manage_url
The event in the host's Neegma dashboard.
attendee_urlstringrequiredevent.attendee_url
The one link to share with guests.
host_urlstringrequiredevent.host_url
Where the host opens the event on the day.
sessionsarray of objectrequiredevent.sessions
curl -X GET https://tryneegma.com/api/v1/connected-events/eventful/evt-123 \
-H "Authorization: Bearer $NEEGMA_TOKEN"{
"event": {
"id": 4182,
"title": "Friday team social",
"status": "draft",
"starts_at": "2026-11-06T16:00:00.000Z",
"timezone": "Europe/London",
"privacy": "private",
"connection": {
"source": "eventful",
"external_id": "evt-123",
"url": "https://eventful.example/e/friday-social"
},
"attendees": {
"going": 1,
"invited": 1,
"not_going": 0,
"total": 2
},
"unpublished_changes": [],
"session_count": 0,
"manage_url": "https://tryneegma.com/dashboard/events/4182",
"attendee_url": "https://tryneegma.com/event/k3x9a7mq2b4z",
"host_url": "https://tryneegma.com/event/k3x9a7mq2b4z/host",
"sessions": []
}
}/api/v1/events/{id}Any of the host's events, by Neegma's ID.
idstringrequiredNeegma's ID for the event, from event.id.
The event.
eventobjectrequiredA Neegma event.
idintegerrequiredevent.id
Neegma's ID for the event. Use it in /events/{id}.
titlestringrequiredevent.title
statusstringrequiredevent.status
One of: draft, scheduled, ready, active, completed
starts_atstring or nullrequiredevent.starts_at
ISO 8601, or null to play now.
timezonestring or nullrequiredevent.timezone
privacystringrequiredevent.privacy
One of: public, private
connectionobject or nullrequiredevent.connection
The platform event this one is connected to, if any.
attendeesobjectrequiredevent.attendees
How many guests the event holds, by status.
unpublished_changesarray of stringrequiredevent.unpublished_changes
What guests cannot see yet. Publish when it is not empty.
session_countintegerrequiredevent.session_count
manage_urlstringrequiredevent.manage_url
The event in the host's Neegma dashboard.
attendee_urlstringrequiredevent.attendee_url
The one link to share with guests.
host_urlstringrequiredevent.host_url
Where the host opens the event on the day.
sessionsarray of objectrequiredevent.sessions
curl -X GET https://tryneegma.com/api/v1/events/4182 \
-H "Authorization: Bearer $NEEGMA_TOKEN"{
"event": {
"id": 4182,
"title": "Friday team social",
"status": "draft",
"starts_at": "2026-11-06T16:00:00.000Z",
"timezone": "Europe/London",
"privacy": "private",
"connection": {
"source": "eventful",
"external_id": "evt-123",
"url": "https://eventful.example/e/friday-social"
},
"attendees": {
"going": 1,
"invited": 1,
"not_going": 0,
"total": 2
},
"unpublished_changes": [],
"session_count": 0,
"manage_url": "https://tryneegma.com/dashboard/events/4182",
"attendee_url": "https://tryneegma.com/event/k3x9a7mq2b4z",
"host_url": "https://tryneegma.com/event/k3x9a7mq2b4z/host",
"sessions": []
}
}/api/v1/events/{id}/sessionsAdds a Live or One-Screen Session. On a private event the session gets a 4-digit join PIN. Counts towards the host's monthly session limit.
idstringrequiredNeegma's ID for the event, from event.id.
modestringrequiredlive: guests join on their phones. one_screen: only the host's screen.
One of: live, one_screen
titlestringDefaults to the event's name.
scheduled_forstring (date-time)ISO 8601. Only for a second or later session; the first follows the event.
template_idintegerA fixed running order of games, from GET /templates.
privatebooleanOverrides the event's privacy for this session.
The new session, its join PIN and the updated event.
sessionobjectrequiredA game session.
idintegerrequiredsession.id
titlestring or nullrequiredsession.title
modestringrequiredsession.mode
One of: live, one_screen
scheduled_forstring or nullrequiredsession.scheduled_for
ISO 8601, or null to follow the event.
statestringrequiredsession.state
One of: not_started, started, finished
template_idinteger or nullrequiredsession.template_id
is_privatebooleanrequiredsession.is_private
host_urlstringsession.host_url
Where the host runs the session.
player_urlstringsession.player_url
Where guests join. Absent on one_screen sessions.
join_pinstring or nullrequiredOn a private session, the PIN to show confirmed guests. Otherwise null.
eventobject or nullrequiredA Neegma event.
idintegerrequiredevent.id
Neegma's ID for the event. Use it in /events/{id}.
titlestringrequiredevent.title
statusstringrequiredevent.status
One of: draft, scheduled, ready, active, completed
starts_atstring or nullrequiredevent.starts_at
ISO 8601, or null to play now.
timezonestring or nullrequiredevent.timezone
privacystringrequiredevent.privacy
One of: public, private
connectionobject or nullrequiredevent.connection
The platform event this one is connected to, if any.
attendeesobjectrequiredevent.attendees
How many guests the event holds, by status.
unpublished_changesarray of stringrequiredevent.unpublished_changes
What guests cannot see yet. Publish when it is not empty.
session_countintegerrequiredevent.session_count
manage_urlstringrequiredevent.manage_url
The event in the host's Neegma dashboard.
attendee_urlstringrequiredevent.attendee_url
The one link to share with guests.
host_urlstringrequiredevent.host_url
Where the host opens the event on the day.
sessionsarray of objectrequiredevent.sessions
warningsarray of stringrequiredWhat Neegma changed or could not keep, without failing the call. Show them to the host.
invalid_request, not_found, limit_reached, upgrade_required, template_not_allowed, event_finished, rate_limited
curl -X POST https://tryneegma.com/api/v1/events/4182/sessions \
-H "Authorization: Bearer $NEEGMA_TOKEN" \
-H "Content-Type: application/json" \
-d @body.json{
"mode": "live",
"template_id": 31
}{
"session": {
"id": 9120,
"title": "Friday team social",
"mode": "live",
"scheduled_for": null,
"state": "not_started",
"template_id": 31,
"is_private": true,
"host_url": "https://tryneegma.com/neeg-host/qz12ab34cd56",
"player_url": "https://tryneegma.com/neeg-host/qz12ab34cd56/channel"
},
"join_pin": "4821",
"event": {
"id": 4182,
"title": "Friday team social",
"status": "draft",
"starts_at": "2026-11-06T16:00:00.000Z",
"timezone": "Europe/London",
"privacy": "private",
"connection": {
"source": "eventful",
"external_id": "evt-123",
"url": "https://eventful.example/e/friday-social"
},
"attendees": {
"going": 1,
"invited": 1,
"not_going": 0,
"total": 2
},
"unpublished_changes": [
"Friday team social is new"
],
"session_count": 1,
"manage_url": "https://tryneegma.com/dashboard/events/4182",
"attendee_url": "https://tryneegma.com/event/k3x9a7mq2b4z",
"host_url": "https://tryneegma.com/event/k3x9a7mq2b4z/host",
"sessions": [
{
"id": 9120,
"title": "Friday team social",
"mode": "live",
"scheduled_for": null,
"state": "not_started",
"template_id": 31,
"is_private": true,
"host_url": "https://tryneegma.com/neeg-host/qz12ab34cd56",
"player_url": "https://tryneegma.com/neeg-host/qz12ab34cd56/channel"
}
]
},
"warnings": []
}/api/v1/events/{id}/publishMakes the event's link show its current name, time and sessions. Publish again after any change; unpublished_changes says when.
idstringrequiredNeegma's ID for the event, from event.id.
The published event.
eventobjectrequiredA Neegma event.
idintegerrequiredevent.id
Neegma's ID for the event. Use it in /events/{id}.
titlestringrequiredevent.title
statusstringrequiredevent.status
One of: draft, scheduled, ready, active, completed
starts_atstring or nullrequiredevent.starts_at
ISO 8601, or null to play now.
timezonestring or nullrequiredevent.timezone
privacystringrequiredevent.privacy
One of: public, private
connectionobject or nullrequiredevent.connection
The platform event this one is connected to, if any.
attendeesobjectrequiredevent.attendees
How many guests the event holds, by status.
unpublished_changesarray of stringrequiredevent.unpublished_changes
What guests cannot see yet. Publish when it is not empty.
session_countintegerrequiredevent.session_count
manage_urlstringrequiredevent.manage_url
The event in the host's Neegma dashboard.
attendee_urlstringrequiredevent.attendee_url
The one link to share with guests.
host_urlstringrequiredevent.host_url
Where the host opens the event on the day.
sessionsarray of objectrequiredevent.sessions
curl -X POST https://tryneegma.com/api/v1/events/4182/publish \
-H "Authorization: Bearer $NEEGMA_TOKEN"{
"event": {
"id": 4182,
"title": "Friday team social",
"status": "scheduled",
"starts_at": "2026-11-06T16:00:00.000Z",
"timezone": "Europe/London",
"privacy": "private",
"connection": {
"source": "eventful",
"external_id": "evt-123",
"url": "https://eventful.example/e/friday-social"
},
"attendees": {
"going": 1,
"invited": 1,
"not_going": 0,
"total": 2
},
"unpublished_changes": [],
"session_count": 1,
"manage_url": "https://tryneegma.com/dashboard/events/4182",
"attendee_url": "https://tryneegma.com/event/k3x9a7mq2b4z",
"host_url": "https://tryneegma.com/event/k3x9a7mq2b4z/host",
"sessions": [
{
"id": 9120,
"title": "Friday team social",
"mode": "live",
"scheduled_for": null,
"state": "not_started",
"template_id": 31,
"is_private": true,
"host_url": "https://tryneegma.com/neeg-host/qz12ab34cd56",
"player_url": "https://tryneegma.com/neeg-host/qz12ab34cd56/channel"
}
]
}
}/api/v1/templatesTemplates the host can use: their own, ones they bought, and Neegma's. A template fixes a session's running order of games.
The templates.
templatesarray of objectrequiredidintegerrequiredtemplates[].id
titlestringrequiredtemplates[].title
descriptionstring or nullrequiredtemplates[].description
sourcestringrequiredtemplates[].source
One of: neegma, bought, mine
gamesarray of objectrequiredtemplates[].games
curl -X GET https://tryneegma.com/api/v1/templates \
-H "Authorization: Bearer $NEEGMA_TOKEN"{
"templates": [
{
"id": 31,
"title": "Office icebreakers",
"description": "Three quick games to get a team talking.",
"source": "neegma",
"games": [
{
"id": "two-truths-and-a-lie",
"title": "Two Truths and a Lie"
},
{
"id": "trivia",
"title": "Trivia"
}
]
}
]
}