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.
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"
}'{
"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.
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
}'{
"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.
{
"speaker_assignments": [
{
"speaker_id": 801,
"role": "Moderator"
},
{
"speaker_id": 802,
"role": "Speaker"
}
]
}{}{
"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.