Consulting Meetings Query
Note: The Teachify Admin API is currently under development and not yet available for public use. This documentation is provided for preview purposes only.
Endpoint and authentication. All admin queries are sent to
POST /admin/graphql— not/graphql, which is the public school API. Authenticate with ansk_live_…API key in theX-Teachify-API-Keyheader. See the API Overview for details.
Overview
Section titled “Overview”The Consulting Meetings API allows you to retrieve information about individual consulting meetings (time slots) scheduled under your school’s consulting services. Each meeting has a lifecycle state, an optional hosting configuration (Zoom, live session, or custom), enrolled attendees, and attendee ratings.
A consulting meeting exposes three distinct person-related fields that answer different questions and are not interchangeable:
lecturerId— the marketing profile / URL slug for the meeting page (resolve via thelecturersquery). Does not control who runs the meeting.hostUserId— the user (school owner or teaching assistant) who actually hosts the session (resolve via themeetingHostsquery).hostEmail— the Zoom license email used to host, only meaningful whenhostingTypeiszoom(resolve via thezoomHostsquery).
Both queries require the courses:read scope.
Available Queries
Section titled “Available Queries”consultingMeetings
Section titled “consultingMeetings”Returns a paginated list of meetings under the school’s consulting services, ordered by start time (newest first) — startedAt DESC, id DESC. The id tiebreak keeps paging stable when two meetings share a start time.
Parameters:
| Parameter | Type | Description |
|---|---|---|
filter | AdminConsultingMeetingFilter | Filter criteria (see Filtering) |
page | Int | Page number for pagination |
perPage | Int | Number of items per page (default: 20, max: 50) |
limit | Int | Alternative to perPage |
Returns:
- AdminConsultingMeetingPage object with:
nodes: Array of AdminConsultingMeeting objectscurrentPage: Current page numberhasNextPage: Whether there are more pageshasPreviousPage: Whether there are previous pagesnodesCount: Total number of items matching the querytotalPages: Total number of pages
Example:
query { consultingMeetings( page: 1, perPage: 10 ) { nodes { id title state startedAt endedAt serviceId lecturerId hostUserId hostingType price currency attendeeCount createdAt updatedAt } currentPage hasNextPage hasPreviousPage nodesCount totalPages }}consultingMeeting
Section titled “consultingMeeting”Returns a single consulting meeting by ID, scoped to the current organization. Returns null if the meeting is not found, does not belong to this school, or is not under a consulting service.
Parameters:
| Parameter | Type | Description |
|---|---|---|
id | String! | The unique identifier of the consulting meeting |
Returns:
- A single AdminConsultingMeeting object, or
nullif not found.
Example:
query { consultingMeeting(id: "meeting-123") { id title state startedAt endedAt serviceId hostUserId hostEmail hostingType joinUrl attendeeCount attendees { id name email } attendeeRatings { rate } }}ConsultingMeeting Object
Section titled “ConsultingMeeting Object”The AdminConsultingMeeting object contains the following fields:
| Field | Type | Description |
|---|---|---|
id | String! | Unique identifier |
title | String | Meeting title |
description | String | Meeting description |
state | String! | AASM state: available, scheduled, or canceled |
startedAt | Int | Unix timestamp |
endedAt | Int | Unix timestamp |
serviceId | String | ID of the parent ConsultingService (target). Use the consultingServices admin query to resolve details |
lecturerId | String | Marketing profile attached to the meeting — drives the lecturer slug, URL routing, and slot-overlap detection. Not the person who hosts the session — see hostUserId. Use the lecturers admin query to resolve profile details |
hostUserId | String | The user (school owner or a teaching assistant) who actually hosts the meeting. Sourced from meetings.hosts[0].id; null on legacy rows where no host was selected |
hostEmail | String | Zoom license email used to host this meeting when hostingType is zoom. Null for non-Zoom hosting types or when the school had no Zoom licenses configured |
hostingType | String | Possible values: zoom, live_session, custom |
hostingId | String | External hosting platform meeting ID (e.g. Zoom meeting ID) |
joinUrl | String | Pre-set join URL for zoom/custom hosting types |
maxAttendeeCapacity | Int | Maximum students allowed; null or 0 means unlimited |
price | Float | Meeting price |
currency | String! | Currency code for the price |
attendeeCount | Int! | Current number of enrolled students |
attendees | [AdminUser!]! | Enrolled students |
ratingForm | Form | The custom rating form for this meeting, resolved from its consulting service. Null means the default rating (score 0.5-10 + comment) is used. Its fields define what an integrator must submit when rating this meeting |
attendeeRatings | [AdminConsultingAttendeeRating!]! | Enrolled students paired with the rating recorded for them by a TA/grader after the session (a default rate or a custom-form submission). Entries with both null have not been rated yet |
discardedAt | Int | Unix timestamp; non-null when soft-deleted |
createdAt | Int! | Unix Timestamp. When the meeting was created |
updatedAt | Int! | Unix Timestamp. When the meeting was last updated |
Meeting states
Section titled “Meeting states”The state field carries the meeting’s AASM lifecycle state:
| State | Meaning |
|---|---|
available | Slot is open; no students enrolled (or all have been removed) |
scheduled | At least one student has been confirmed for this slot |
canceled | Slot has been canceled |
Filtering
Section titled “Filtering”The consultingMeetings query accepts a filter parameter of type AdminConsultingMeetingFilter. This allows you to narrow down results based on the following criteria.
Available Filters
Section titled “Available Filters”| Filter Field | Type | Description |
|---|---|---|
serviceId | String | Filter by parent ConsultingService ID |
lecturerId | String | Filter by assigned lecturer ID |
hostUserId | String | Filter by the hosting user (school owner or teaching assistant) recorded in meetings.hosts[0].id. Use this — not lecturerId — to fetch the meetings a given TA actually hosted |
state | AdminMeetingState | AASM state filter (available, scheduled, canceled) |
startedAfter | Int | Unix timestamp; matches meetings with startedAt >= value |
startedBefore | Int | Unix timestamp; matches meetings with startedAt <= value |
Filter Examples
Section titled “Filter Examples”Find scheduled meetings for a specific service:
query { consultingMeetings( filter: { serviceId: "service-123", state: scheduled } ) { nodes { id title state startedAt } nodesCount }}Find meetings hosted by a specific TA within a time window:
query { consultingMeetings( filter: { hostUserId: "user-456", startedAfter: 1704067200, startedBefore: 1706745600 } ) { nodes { id title hostUserId startedAt endedAt } nodesCount }}Related Queries
Section titled “Related Queries”Two companion queries help resolve the person-related fields on a consulting meeting:
meetingHosts— resolveshostUserIdto the school owner or teaching assistant who hosts a session.zoomHosts— resolveshostEmailto the Zoom license used for hosting whenhostingTypeiszoom.
Both are school-wide, return a non-paginated array, and require the courses:read scope. Use them before writing a meeting to populate host pickers or pre-validate input, rather than recovering from the valid_options= suffix on a MEETING-011 / MEETING-012 failure after a bad write.
meetingHosts
Section titled “meetingHosts”Returns the school owner plus all undiscarded teaching assistants — the exact user pool accepted by hostUserId on bulkCreateConsultingMeetings and updateConsultingMeeting. The owner row comes first, then teaching assistants ordered by user.createdAt ascending. A school owner who also holds the teaching_assistant role is deduplicated to a single owner row.
Returns: [AdminMeetingHost!]!
| Field | Type | Description |
|---|---|---|
role | AdminMeetingHostRole! | How the user qualifies for the pool: owner (the school owner) or teaching_assistant |
user | AdminUser! | The user record. Pass user.id as hostUserId when creating or updating a meeting |
query { meetingHosts { role user { id name email createdAt } }}Note: The admin API does not gate this pool on the school admin UI’s
learning_centerfeature flag — teaching assistants are always returned, so the API pool can be wider than the host list the school admin UI shows. An empty result means the school has no eligible hosts (the owner is soft-deleted and no teaching assistants exist); consulting meeting mutations then failMEETING-012.
zoomHosts
Section titled “zoomHosts”Returns the Zoom license seats configured under the school’s active Zoom integration — the exact set of values accepted by hostEmail when hostingType is zoom. Order matches Settings → Integrations → Zoom. Returns an empty list when the school has no active Zoom integration (the same precondition MEETING-009 enforces) or when the integration has no license metadata recorded.
Returns: [AdminZoomHost!]!
| Field | Type | Description |
|---|---|---|
email | String! | Zoom license email. Pass as hostEmail on consulting meeting mutations |
name | String | Display name configured for this license seat; null if not set |
query { zoomHosts { email name }}