Runs

Fetch the status, configuration, and problems of past upload requests and realtime sessions.

A run is the record of one upload request or one realtime session. Each measured upload request and each realtime session is recorded as a run. The run endpoints return its status, the configuration it ran under, and the problems it reported, both while a session is in progress and after it closes. Measurements come only from the upload response or the session, so store the results you need. Recording never delays a measurement, so on rare occasions a run, or part of one, is not recorded.

EndpointReturns
GET /v1/expression/runPaginated list of your organization’s runs.
GET /v1/expression/run/{run_id}One run: its status and configuration.
GET /v1/expression/run/{run_id}/eventsThe problems the run reported, in order.

Run IDs

A run’s run_id is the identifier it was given when it started:

  1. For an upload request, the run_id in the response from Audio upload or Image upload.
  2. For a realtime session, the session_id in session.created. See Sessions.

A run can take a moment to appear after the response or session.created message that carries its ID.

An audio upload is recorded as a run once its audio reaches measurement, and an image upload once its images reach the checks. A request that fails after that point, including an image upload whose first image fails its check, is recorded with status errored. One rejected earlier has no run. Error bodies carry a request_id but no run_id; quote the request_id when contacting support.

Runs are scoped to your organization. A run in another organization returns 404, the same as a run that does not exist.

Run status

StatusDescription
liveThe run is in progress.
endedThe run completed.
erroredThe run ended because of a failure, or because the connection was lost. A live run the server has not heard from in five minutes is also reported errored, and reads live again if the server hears from it.

Listing runs

GET /v1/expression/run returns your organization’s runs, newest first. The filters combine, so the request below returns the audio upload requests that started on October 9, 2024.

curl -G https://api.cloud.hume.ai/v1/expression/run \
-H "X-Hume-Api-Key: $HUME_API_KEY" \
-d endpoint=audio \
-d mode=file \
-d started_after=2024-10-09T00:00:00Z \
-d started_before=2024-10-10T00:00:00Z

To send these requests from this page, open a panel and enter your API key.

GET
https://api.cloud.hume.ai/v1/expression/run
page_size
Defaults to 50

How many runs to return, from 1 to 200.

cursor

The next_cursor of the previous page. See Pagination.

user_id

Only runs made by this user.

status

Only runs with this status: live, ended, or errored.

mode

Only runs that reached the API this way: file for upload requests, realtime for sessions.

endpoint

Only runs measured by this endpoint: audio or video.

started_after

Only runs that started at or after this time, in RFC 3339 format.

started_before

Only runs that started before this time, in RFC 3339 format.

started_after includes its boundary and started_before excludes it, so consecutive time windows that share a boundary neither skip a run nor return one twice.

200 OK
{
"runs": [
{
"run_id": "01926f3c-d33c-7c9f-9c91-4502d80834d5",
"user_id": "8d3f4a1e-6b2c-4f7d-9e0a-1b2c3d4e5f60",
"status": "ended",
"endpoint": "audio",
"mode": "file",
"started_at": "2024-10-09T03:05:10.204Z",
"ended_at": "2024-10-09T03:05:11.463Z",
"bytes_received": 160000,
"bytes_recorded": 160000,
"metered_seconds": 10.0
}
],
"next_cursor": "2024-10-09T03:05:10.204000Z|01926f3c-d33c-7c9f-9c91-4502d80834d5"
}
run_id

The run’s ID. See Run IDs.

user_id

The Hume user who made the run.

status
endpoint

audio or video.

mode

file for an upload request, realtime for a session.

started_at, ended_at

When the run started and ended. ended_at is null while the run is in progress. For a run reported errored because the server stopped hearing from it, ended_at is the last time the server heard from it.

bytes_received

Bytes of media the server took in. A realtime video frame counts once it passes the send-rate check, even if it is then rejected as invalid. null until the run ends, and for a run whose end was never recorded.

bytes_recorded

How far the server got in storing the run’s media, in bytes. Media that could not be stored is included, so this can exceed what was kept. null when the run’s media was not being stored, or when the server has not yet reported how much it stored, as early in a live run.

metered_seconds

Billable seconds for the run. For audio, the duration of the audio the server took in. For video, one third of a second for each frame or image the server took in, regardless of frame rate, including a realtime frame rejected as invalid after it passed the send-rate check. A run that took in any media is billed at least 10 seconds, applied when the run ends. Updated while a realtime session is in progress. A failed upload request is not billed, and its run reports 0. See Billing.

Pagination

The list endpoint and the events endpoint return one page at a time. Every page but the last carries a next_cursor; on the last page the field is absent. Pass it back unchanged as cursor to fetch the next page. A cursor the endpoint did not issue is rejected with invalid_request.

Getting a run

GET /v1/expression/run/{run_id} returns the fields of the list, plus the configuration the run ran under and, for a realtime session, how the connection ended.

curl https://api.cloud.hume.ai/v1/expression/run/01926f3a-5b1c-7d2e-8f40-3a9b7c1d2e5f \
-H "X-Hume-Api-Key: $HUME_API_KEY"
GET
https://api.cloud.hume.ai/v1/expression/run/:run_id
200 OK
{
"run_id": "01926f3a-5b1c-7d2e-8f40-3a9b7c1d2e5f",
"user_id": "8d3f4a1e-6b2c-4f7d-9e0a-1b2c3d4e5f60",
"status": "ended",
"endpoint": "audio",
"mode": "realtime",
"started_at": "2024-10-09T03:02:28.380Z",
"ended_at": "2024-10-09T03:02:55.104Z",
"close_code": 1000,
"close_reason": "client_request",
"bytes_received": 832000,
"bytes_recorded": 832000,
"metered_seconds": 26.0,
"config": {
"schema": "v4",
"audio": {
"type": "audio/pcm",
"encoding": "s16le",
"sample_rate": 16000,
"channels": 1
},
"measurement_timer_ms": 3000
}
}
close_code

The WebSocket close code the session ended with, or 1011 if the connection was lost without a close frame. null for upload requests, for sessions still in progress, and for sessions whose close was not recorded, such as when the client’s close frame carried no code.

close_reason

Why the session ended. When the server closed it: client_request, server_shutdown, idle_timeout, or error. When the connection was lost without a close frame: error. When the client closed the WebSocket: the reason text from its close frame. null for upload requests, for sessions still in progress, and for sessions whose close was not recorded, such as when the client’s close frame carried no code.

config

The configuration the run ran under, with every default filled in. An audio run has audio and measurement_timer_ms. A video run has image and face, with face.threshold and face.min_size.

config.schema

The layout of the configuration document, v4. If you store configurations, branch on it so a later layout is recognized rather than misread.

Getting events

GET /v1/expression/run/{run_id}/events returns the problems a realtime session reported, in order: the frames it rejected and the failures it hit. A run with no problems has an empty log. The only event an upload request can record is video_recording_abandoned, on the image upload endpoint; any other upload problem fails the whole request and appears in its error response. Two kinds of problem are left out of the log: errors that answered a text message, such as config_invalid, and an internal_error on the audio endpoint, which shows as the run’s errored status.

curl https://api.cloud.hume.ai/v1/expression/run/01926f3a-5b1c-7d2e-8f40-3a9b7c1d2e5f/events \
-H "X-Hume-Api-Key: $HUME_API_KEY"
GET
https://api.cloud.hume.ai/v1/expression/run/:run_id/events
200 OK
{
"events": [
{
"seq": 1,
"at": "2024-10-09T03:02:31.720Z",
"kind": "invalid_audio_frame",
"detail": {
"detail": "binary audio frame must contain complete 16-bit PCM samples"
}
},
{
"seq": 2,
"at": "2024-10-09T03:02:40.344Z",
"kind": "rate_limited"
}
],
"at_cap": true,
"capped_kinds": ["rate_limited"],
"gaps": false
}

The endpoint takes page_size (default 50, from 1 to 200) and cursor, and pages as described in Pagination.

events[].seq

The entry’s position in the log.

events[].at

When the event was recorded.

events[].kind

What happened. See the table below.

events[].detail

Details that depend on kind: the reason a frame was rejected (detail), the size limit a message exceeded (limit_bytes), whether a measurement failure was temporary and how many failed in a row (retryable, consecutive), or why recording stopped (reason). Absent for rate_limited.

at_cap

true when at least one kind of event reached its logging limit for the run. Events of that kind after the limit were not logged, so the log may undercount them. capped_kinds names the kinds. When gaps is true, at_cap can be false even though a limit was reached.

capped_kinds

The kinds that reached their limit. Empty when none did.

gaps

true when entries are missing from the log: events that were numbered but never stored.

KindEndpointDescription
invalid_audio_frameAudioAn audio frame was rejected.
invalid_image_frameVideoAn image frame was rejected, or face detection failed on a frame and the session received an internal_error for it.
rate_limitedBothMedia arrived faster than the send rate, and a frame was rejected.
inference_failedVideoA frame was skipped because its measurement failed. The session received an internal_error for it.
message_too_largeBothA message exceeded the size limit, and the session ended.
video_recording_abandonedVideoThe server stopped storing the run’s frames. Results were still delivered. The server no longer records this event, so it appears only on older runs.

Errors

The run endpoints return the error body described in HTTP errors. A 401 carries only a message, and a request_id when an API key was rejected.

StatusCodeDescription
400invalid_requestA query parameter has a value the endpoint does not accept, or cursor is not one the endpoint issued. Sent by the list and events endpoints.
401NoneThe request carried no valid API key or access token.
404not_foundNo run with this ID exists in your organization, or no endpoint exists at this path.
405method_not_allowedThe endpoint does not accept this HTTP method. The Allow header lists the methods it does accept.
500internal_errorThe server failed while serving the request. Retry it. If the failure recurs, contact Hume with the request_id.
503server_busyThe service is too busy to serve the request now. Wait the number of seconds in the Retry-After header, then retry.

Next steps