Menu

Guide

Connect events from your platform

Link events made on your platform to Neegma, map your own fields, and add games your guests can join.

Updated Nov 2, 2026 ยท 8 min read

When a host creates an event on your platform, one call creates its Neegma event and keeps it in step. The host then adds games, and your guests get one link to join them on the day.

You will:

  1. Let the host connect their Neegma account.
  2. Send the event, mapped from your own fields.
  3. Add a game session.
  4. Publish, and share the link with guests.

Before you start#

  • An OAuth 2.1 library that supports the authorization code flow with PKCE. Most do.
  • A client ID for your app, which the host's sign-in needs. Your library can create one for you from the discovery address in step 1 (dynamic client registration), or contact us with your app's name, logo and redirect URLs and we create it.

Every request below goes to https://tryneegma.com/api/v1 with the host's access token:

Authorization: Bearer <access token>
Content-Type: application/json

Step 1: Let the host connect their account#

Send the host through the OAuth authorization code flow with PKCE. Your library can find the sign-in and token endpoints from this address:

https://tryneegma.com/.well-known/oauth-protected-resource

The host signs in, or creates a free account in the same window. New accounts are confirmed with a 6-digit code from their email, so they never leave the window.

The sign-in window: create an account with Google or email

Then they allow your app to use their account. When they choose Allow, you receive the authorization code. Exchange it for an access token and a refresh token.

The consent screen, naming your app and where it sends the host back to

The screen shows your app's name and the address it sends the host back to. Until we have checked your app, it also shows a note saying so; contact us to have it checked.

Step 2: Send the event#

PUT /api/v1/connected-events/{source}/{external_id}
  • source is a short name for your platform, such as eventful: lowercase letters, digits and hyphens.
  • external_id is the event's ID on your platform.

The first call creates the Neegma event and answers 201. Every later call with the same source and external_id updates it and answers 200. Send it whenever the event changes. It is safe to retry: it never creates a second event.

Send your own fields, with a mapping#

Send your event exactly as your platform stores it, under data. Under mapping, say which of your fields holds each piece Neegma needs.

{
    "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"
            }
        ]
    },
    "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"
            }
        }
    }
}

Fields are dot paths into data, such as event.start_at or hosts.0.name.

Or send Neegma's field names#

If you would rather map on your side, send the fields directly:

{
    "title": "Friday team social",
    "starts_at": "2026-11-06T16:00:00Z",
    "timezone": "Europe/London",
    "url": "https://eventful.example/e/friday-social",
    "privacy": "private",
    "attendees": [
        {
            "external_id": "g1",
            "name": "Ada Lovelace",
            "email": "ada@example.com",
            "status": "going"
        }
    ]
}

What you can map#

FieldWhat it holdsNotes
titleThe event's nameRequired. 2 to 50 characters; longer names are cut.
starts_atWhen it startsISO 8601. Leave it out to keep the current time.
timezoneWhere it was plannedAn IANA name, such as Europe/London.
urlYour event pageReturned with the event, so you can match it up.
privacypublic or privateTranslate your own values with values and default.
attendees.listYour list of guestsPoints at an array in data.
attendees.nameThe guest's nameOne field, or up to three joined with a space.
attendees.emailThe guest's emailOptional. Accepted, but not stored yet: nothing in Neegma uses it.
attendees.external_idThe guest's ID on your platformOptional. Stops the same guest being added twice.
attendees.statusgoing, invited or not_goingTranslate your own values with values and default. Without it, guests are going.

Types, limits and every response field are in the API reference.

Attendees. Send the full list each time: it replaces the list Neegma holds. Leave attendees out to keep the current list. Neegma keeps each guest's name, status and your ID for them, and returns the counts with the event, with a warning if more guests are going than the host's plan lets join a session. Send only what games need: no photos or other personal data.

Privacy. A private event puts a 4-digit join PIN on every session you add to it. Show the PIN only to confirmed guests. Private sessions need a paid Neegma plan. If Neegma cannot make a session private, it is not added and the call fails with private_session_failed, so try again.

The response#

{
    "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": 0, "not_going": 0, "total": 1 },
        "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": []
}

Keep event.id for the next steps. You can read the event back at any time with GET /api/v1/connected-events/{source}/{external_id} or GET /api/v1/events/{id}.

warnings lists anything Neegma changed or could not keep, without failing the call. For example: the title was cut to 50 characters, a guest had no name, or the event has already started so its time was not moved. Show them to the host.

Events your organisers have paid for#

If you sell Neegma events to your organisers, for example as an add-on to your own plans, you buy event passes from us under a partner agreement. Tell us which pass each event uses with event_pass, in either kind of request:

{
    "title": "Summer launch party",
    "starts_at": "2026-12-04T18:30:00+00:00",
    "event_pass": { "paid": true, "plan_code": "party_pass_100", "reference": "order-8841-1" }
}
FieldWhat it does
paidtrue puts the pass on this event. false takes your pass off it.
plan_codeThe pass bought: party_pass_50, party_pass_100, party_pass_150 or party_pass_200 (guests).
referenceYour ID for the pass, such as your order line. One reference is one pass.
  • Moving a pass. Send the same reference for another event and the pass moves there. A pass moves or comes off only until guests have joined its event; after that, the call fails with pass_in_use.
  • One pass per event. Sending a new pass for an event that already has one replaces it. Before any guest joins, the old pass is free for another event and event_pass.released names it. Once guests have joined, the old pass is used and event_pass.spent names it.
  • A pass that cannot be saved fails the call. The event itself is still saved, so fix the pass and send the same call again. The codes are pass_in_use, pass_used (that pass is already spent), pass_downgrade (guests have joined, so the event cannot move to a smaller pass) and event_pass_failed (try again).
  • Deleted events. If the host deletes an event before anyone joins, its pass comes back to you. Once guests have joined, the pass is used.
  • Without an agreement the call is refused with event_pass_not_allowed. Contact us to set one up.

Step 3: Add a game session#

POST /api/v1/events/{id}/sessions
{ "mode": "live", "template_id": 31 }
FieldWhat it does
modelive: guests join on their phones. one_screen: only the host's screen; the room plays together.
template_idOptional. A fixed running order of games. List the host's templates with GET /api/v1/templates. Without it, the host picks games when the session starts.
titleOptional. Defaults to the event's name.
scheduled_forOptional, ISO 8601. Only for a second or later session; the first follows the event.
privateOptional. Overrides the event's privacy for this session.

The response includes the session's player_url, and on a private event its join_pin. Each session counts towards the host's monthly session limit.

Step 4: Publish and share#

POST /api/v1/events/{id}/publish

Publishing makes the event's link show its current name, time and sessions. Until then, unpublished_changes lists what guests cannot see yet. Publish again after any change.

Share attendee_url with your guests: it is the one link for the whole event. The host opens host_url on the day to run the games.

Errors and limits#

Errors share one shape: a stable code for your code to check, and a message you can show the host.

{
    "error": {
        "code": "limit_reached",
        "message": "Monthly session limit reached.",
        "upgrade_url": "https://tryneegma.com/pricing"
    }
}

The API reference lists every code and the rate limits. The host's Neegma plan applies as it does in Neegma: sessions per month, players per session, and private sessions.