Skip to content
Core API
Esc
navigateopen⌘Jpreview
On this page

Build an agenda and connect speakers

Turn event notes into a reviewed agenda, create speakers and sessions, and connect them through the Core API.

You can use the Core API to create speakers and content sessions, then connect them. An AI agent can help structure messy notes and prepare the requests. It needs an authorized tool capable of making HTTPS requests to execute them; the Brella agent skill supplies the workflow and API knowledge.

Review the source material

Ask the agent to extract a table with session title, date, start time, duration, track, location, description and speakers. Keep missing values marked as unresolved. Confirm the event’s timezone and dates, duplicate speaker names, and whether each item should create or update a record.

Use a stable external ID for each session and speaker. Keep a mapping from that source ID to the returned Brella ID. A matching name alone is not a reliable identity; ask about ambiguous matches.

Prepare permissions

Your Core API token needs access to the event and these resource scopes:

Resource Actions and fields for this recipe
Events Read the event’s name and dates. Obtain the timezone from the organizer; this Core resource does not expose a timezone field.
Tracks Read existing tracks; enable create with name if you need a new content track.
Speakers Read/create; allow external_id, first_name, last_name and any optional profile inputs. Enable the external_id query filter for reconciliation.
Content sessions Read/create/update; allow external_id, title, track_id, start_time, duration, speaker_assignments, and content or location if used. Enable the external_id query filter and the speaker_assignments read association.

Select response fields you need for verification. Write-response fields are separate from readable fields. You can always save the returned data.id.

Create or reuse the speakers

Read existing speakers, using an enabled external_id filter when available. Create only those that are missing. The speaker resource requires first_name; optional biography text is accepted by bio and normalized by Brella.

Build a request

Example data only. No request is sent.

POST
Choose the destination IDs
Start with these fields

External identifier.

Speaker first name.

Last name.

Add optional fields (9)

Honorific.

Middle name.

Job title.

Company name.

DraftJS JSON or HTML/text. Sanitized and stored as DraftJS content.

Featured order.

Display order.

Entries use key plus value or values.

HTTP(S) URL or base64 data URI. Blank on PATCH removes the current photo.

Use the API address and token from your environment. Set up authentication.

curl --fail-with-body --silent --show-error --globoff --max-time 30 --request POST \
  --url "${BRELLA_API_BASE_URL}"'/api/core/organizations/123/events/456/speakers' \
  --header "Accept: application/vnd.brella.v4+json" \
  --header "Brella-API-Access-Token: ${BRELLA_API_ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data-raw '{
  "external_id": "SPEAKER-42",
  "first_name": "Taylor",
  "last_name": "Ng"
}'
201 CreatedIllustrative response
{
  "data": {
    "id": "1201",
    "type": "speaker"
  }
}

The token scope determines returned fields. This selector illustrates that configuration; it does not change your token or the request.

Save the actual IDs from the 201 Created responses. The numbers in the examples are fictional. Core does not expose a speaker DELETE operation, so do not plan an automatic rollback that depends on one.

Resolve the content track

Read /tracks for this event and select a content or external-content track. Networking tracks cannot hold content sessions. If necessary, create a track with name; the Core track create operation creates a content track.

View the minimal cURL example
curl --fail-with-body --silent --show-error --globoff --max-time 30 --request POST \
  --url "${BRELLA_API_BASE_URL}"'/api/core/organizations/123/events/456/tracks' \
  --header "Accept: application/vnd.brella.v4+json" \
  --header "Brella-API-Access-Token: ${BRELLA_API_ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data-raw '{
  "name": "Main stage"
}'

Using an existing, verified track_id makes the import easier to review. The session track_name input can also find or create a content track when no track ID is supplied.

Create one session first

Provide an ISO 8601 start time with an explicit timezone offset and a duration in minutes. Convert the agreed event-local time to that instant deliberately. Brella’s timeslot flow applies event timezone compatibility logic; verify the displayed time in the organizer agenda instead of assuming a returned timestamp can be echoed back unchanged.

The session and its end time must fit within the event dates. Use duration; although end_time is exposed in the wrapper, the current write parameter allowlist discards it.

Build a request

Example data only. No request is sent.

POST
Choose the destination IDs
Start with these fields

Must identify a content or external-content track in the event.

Converted through the event's time-zone compatibility logic.

Minutes. With start_time, it supplies the model-required end time.

Session title.

Add optional fields (31)

Finds or creates an event content track when track_id is absent.

Parent session reference.

Session subtitle.

DraftJS object with a blocks array and entityMap. Plain text and HTML strings are rejected. Use the description field in the request builder to generate the object.

External integration identifier.

Stream URL.

Highlight ordering.

Display setting.

Session orientation.

Enables session RSVP behavior.

Returned as uses-registrant-list.

Ticket QR check-in setting.

RSVP registration state.

Capacity.

Color value.

Rating setting.

Cancellation setting.

Reserved capacity.

Section label.

Section label.

Map URL.

Main sponsor; must belong to the event.

Full replacement; entries use sponsor_id and optional label. Array order sets position.

Full replacement; entries use speaker_id and optional role. Array order sets position.

Entries use key plus value or values.

Gating lists; all IDs must belong to the event.

Rating gating lists.

Child sessions.

Send tag names as strings. Core rejects ID objects because the input allows scalar array items only. [] clears tags and locations.

Location name. Brella finds or creates an event location tag. Blank clears locations.

Base64 data URI. Blank on PATCH removes the current image.

Write a session description

Converted into the DraftJS JSON object required by content. Leave blank to use the optional content input instead.

Use the API address and token from your environment. Set up authentication.

curl --fail-with-body --silent --show-error --globoff --max-time 30 --request POST \
  --url "${BRELLA_API_BASE_URL}"'/api/core/organizations/123/events/456/content-sessions' \
  --header "Accept: application/vnd.brella.v4+json" \
  --header "Brella-API-Access-Token: ${BRELLA_API_ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data-raw '{
  "title": "Opening keynote",
  "track_id": 501,
  "start_time": "2026-09-03T09:00:00Z",
  "duration": 60
}'
201 CreatedIllustrative response
{
  "data": {
    "id": "1201",
    "type": "content-session"
  }
}

The token scope determines returned fields. This selector illustrates that configuration; it does not change your token or the request.

Use Add optional fields to include external_id, location and speaker_assignments. Each assignment contains a real speaker_id from this event and an optional role, such as Speaker or Moderator. Array order determines display position.

For a session description, use the builder’s Write a session description control. It converts plain text to the DraftJS JSON object required by content. A plain string or HTML string is rejected for this field. Speaker bio has different rules and accepts text.

Connect or update speakers on an existing session

PATCH the content session with the full intended speaker_assignments array. There is no separate Core speaker-assignment endpoint, and the speaker resource cannot manage session assignments.

What does this PATCH change?

Compare omitted, replaced and cleared collections. These are conceptual field values, not a live API response.

Before
{
  "speaker_assignments": [
    {
      "speaker_id": 801,
      "role": "Moderator"
    },
    {
      "speaker_id": 802,
      "role": "Speaker"
    }
  ]
}
PATCH body
{}
After
{
  "speaker_assignments": [
    {
      "speaker_id": 801,
      "role": "Moderator"
    },
    {
      "speaker_id": 802,
      "role": "Speaker"
    }
  ]
}

Omitting the field keeps the existing collection.

Send every speaker that should remain. Array order determines the assignment position.

Omit speaker_assignments to preserve the existing assignments. Send [] only when you intend to remove all of them. Do not send a one-speaker array to append someone to a session that already has speakers.

Verify, then finish the batch

Read the created session by its returned ID with include=speaker-assignments,track. The scope must allow these associations and their fields. Check each speaker ID and role, title, duration, location and the time shown in the organizer agenda.

Once the sample is correct and the remaining plan is approved, process the rest sequentially or with modest bounded concurrency. Keep a per-item log of source ID, request purpose, returned ID and result. Never log the API token.

Each write request has its own transaction; the entire import is not atomic. If a request times out, look up its external ID before retrying. Session and speaker external IDs are unique within an event when present, but POST is not an upsert and a duplicate can fail validation. Stop on an ambiguous match or permission failure, fix the cause, then resume from the recorded results.

There is no general Core session draft or publish input in this workflow. Treat writes as changes to the event’s agenda; a locally reviewed plan is not an unpublished server-side draft.

The agent guide includes a reusable prompt and a structured plan template for this exact task.