---
title: "The metronome that grades a person: five drills, each scored in milliseconds on a staircase."
method: POST
path: "/api/agents/run/pull_practice"
tags: ["Lab"]
---

# The metronome that grades a person: five drills, each scored in milliseconds on a staircase.

`POST /api/agents/run/pull_practice`

## Request

- Base URL: `https://tomorrowlives.com`
- URL: `https://tomorrowlives.com/api/agents/run/pull_practice`
- Auth: HTTP bearer

Grades a practice of five drills: match (the spread of the taps against the click), hold (the click falls silent and the person keeps the beat), follow (the click moves its tempo once, at a beat nobody is told), lead (the click follows the person) and duet (the click meets the person a quarter of the way). Each drill is rounds of taps against a click, graded on one number in milliseconds against its level's tolerance, and printed beside the input's own jitter (practice.input: the clock that stamps the taps and its stated jitter), with a sentence saying so when the input cannot tell the person's spread from its own. The staircase is pinned: two passes in a row move a drill up one level and a miss moves it down one, 20 levels at most. The answer's session (each drill's next level and score) goes back in as the next practice's history, oldest first, and a drill the history holds gets a trend over the sessions. A drill's recorded rounds ([{clicks_ms, taps_ms}], a client's own click and tap times) are graded as played; without them a simulated person (a timekeeper and a motor, correcting toward the click) plays the drill, and practice.person sets it. The engine plays no click and hears no input: the client does both. Give a practice document (pull_schema lists its keys under practice), or nothing, or seed alone, for the default practice of all five drills. Every sentence is checked for wellness language and the answer carries the not-a-medical-device sentence; a drill name the check refuses refuses the whole answer. Answers at once, within 30 seconds. Costs 1 unit.

## Request body

- object
  - `practice` object: The practice document: the five drills and the taps recorded for each, as JSON.
  - `seed` integer: A whole number that makes the run reproducible: the same seed and inputs give the same answer.

## Response `200`

The job's result and files

- Job
  - `job` string
  - `verb` string
  - `units` integer
  - `ms` integer
  - `result` unknown
  - `files` object[]
    - `name` string
    - `bytes` integer
    - `content_type` string
    - `url` string
    - `url_expires_at` string, date-time

## Other responses

- `400`: The input is not valid
- `401`: No valid API key
- `402`: A pass or a payment is needed: a queued render on the free plan, a unit pack on the free plan (pass_required), a card plan's past-due renewal, or, on the free plan, an owner who has not confirmed their email yet (owner_unconfirmed; a pass needs no confirmation); or a payment did not go through (payment_failed, payment_token_unusable), and nothing was charged
- `403`: The account is suspended, the paying card is not from the United States (region_not_supported), or the address named as its owner said it is not theirs and costed runs are paused until a new owner is named (owner_removed)
- `413`: The input or the output is over its cap; a job stopped by the output cap is not charged
- `422`: The engine refused the input, a limit of the service's refused it (error: video_limit or pull_limit) or stopped the job, or the content policy refused the input (error: content_policy)
- `429`: A limit was hit; reset_at says when it lifts (also in Retry-After)
- `503`: The engines are busy or not installed
- `504`: The job ran past its time and was stopped

---

[API](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines.md) · [All operations](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/llms.txt) · [OpenAPI document](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/revisions/afc3d67322ac?raw)
