Skip to content

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/graphqlnot /graphql, which is the public school API. Authenticate with an sk_live_… API key in the X-Teachify-API-Key header. See the API Overview for details.

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 the lecturers query). Does not control who runs the meeting.
  • hostUserId — the user (school owner or teaching assistant) who actually hosts the session (resolve via the meetingHosts query).
  • hostEmail — the Zoom license email used to host, only meaningful when hostingType is zoom (resolve via the zoomHosts query).

Both queries require the courses:read scope.

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:

ParameterTypeDescription
filterAdminConsultingMeetingFilterFilter criteria (see Filtering)
pageIntPage number for pagination
perPageIntNumber of items per page (default: 20, max: 50)
limitIntAlternative to perPage

Returns:

  • AdminConsultingMeetingPage object with:
    • nodes: Array of AdminConsultingMeeting objects
    • currentPage: Current page number
    • hasNextPage: Whether there are more pages
    • hasPreviousPage: Whether there are previous pages
    • nodesCount: Total number of items matching the query
    • totalPages: 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
}
}

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:

ParameterTypeDescription
idString!The unique identifier of the consulting meeting

Returns:

  • A single AdminConsultingMeeting object, or null if 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
}
}
}

The AdminConsultingMeeting object contains the following fields:

FieldTypeDescription
idString!Unique identifier
titleStringMeeting title
descriptionStringMeeting description
stateString!AASM state: available, scheduled, or canceled
startedAtIntUnix timestamp
endedAtIntUnix timestamp
serviceIdStringID of the parent ConsultingService (target). Use the consultingServices admin query to resolve details
lecturerIdStringMarketing 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
hostUserIdStringThe 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
hostEmailStringZoom 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
hostingTypeStringPossible values: zoom, live_session, custom
hostingIdStringExternal hosting platform meeting ID (e.g. Zoom meeting ID)
joinUrlStringPre-set join URL for zoom/custom hosting types
maxAttendeeCapacityIntMaximum students allowed; null or 0 means unlimited
priceFloatMeeting price
currencyString!Currency code for the price
attendeeCountInt!Current number of enrolled students
attendees[AdminUser!]!Enrolled students
ratingFormFormThe 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
discardedAtIntUnix timestamp; non-null when soft-deleted
createdAtInt!Unix Timestamp. When the meeting was created
updatedAtInt!Unix Timestamp. When the meeting was last updated

The state field carries the meeting’s AASM lifecycle state:

StateMeaning
availableSlot is open; no students enrolled (or all have been removed)
scheduledAt least one student has been confirmed for this slot
canceledSlot has been canceled

The consultingMeetings query accepts a filter parameter of type AdminConsultingMeetingFilter. This allows you to narrow down results based on the following criteria.

Filter FieldTypeDescription
serviceIdStringFilter by parent ConsultingService ID
lecturerIdStringFilter by assigned lecturer ID
hostUserIdStringFilter 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
stateAdminMeetingStateAASM state filter (available, scheduled, canceled)
startedAfterIntUnix timestamp; matches meetings with startedAt >= value
startedBeforeIntUnix timestamp; matches meetings with startedAt <= value

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
}
}

Two companion queries help resolve the person-related fields on a consulting meeting:

  • meetingHosts — resolves hostUserId to the school owner or teaching assistant who hosts a session.
  • zoomHosts — resolves hostEmail to the Zoom license used for hosting when hostingType is zoom.

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.

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!]!

FieldTypeDescription
roleAdminMeetingHostRole!How the user qualifies for the pool: owner (the school owner) or teaching_assistant
userAdminUser!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_center feature 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 fail MEETING-012.

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!]!

FieldTypeDescription
emailString!Zoom license email. Pass as hostEmail on consulting meeting mutations
nameStringDisplay name configured for this license seat; null if not set
query {
zoomHosts {
email
name
}
}