# Drive a job over REST

> **What you will learn**
> Not a chapter to read but one to **do**. Start one job over REST, read its
> progress, and **send it twice on purpose** to see what happens.

## What you need

```
□ 40 minutes
□ HyperTeams running, with one registered working directory
□ curl, or any HTTP client
□ A token
□ Start with a directory that is easy to restore
```

If you have not issued a token yet, [directing work over
REST](/guide/ht-rest-api) covers how.

**Do not paste the token into a chat or an issue.** Keep it inside the terminal
for the whole exercise.

---

## Step 1 — Read before you write (5 min)

**Before creating a job**, confirm a read call works. This keeps authentication
problems and request problems from getting mixed up later.

```
□ You called the list endpoint once
□ You got a 200
□ On 401/403 -> a token problem. Fix it here before moving on
```

**If you are stuck here, do not go to step 2.** Carrying an auth problem into job
creation gives you two causes at once.

---

## Step 2 — Start a read-only job (10 min)

Make the first job one that **changes no files.**

```
Example instruction:
  "List the files in this folder that have no tests. Do not modify any files."
```

### What to look for

```
□ Does the response contain a job id?
□ Can you query progress with that id?
□ Does the same job appear on the dashboard?  <- both surfaces see one thing
```

**The third one matters.** Seeing with your own eyes that REST and the screen show
**the same job** saves you the later "where do I see the ones I started from
code?"

---

## Step 3 — Read the progress (5 min)

Poll the same job **a few times until it finishes.**

| Check | |
|---|---|
| Does the state value change? | □ |
| Where do you read the result when it ends? | □ |
| If it failed, is the reason in the response? | □ |

```
□ How many seconds between polls — write it down
```

**Write that last one down.** When you automate this later, that interval becomes
your design value: too frequent is pure load, too sparse is a slow reaction.

---

## Step 4 — Send it twice on purpose (15 min)

**This is the point of the exercise.** Send the same request **twice in a row.**

```
□ You called it twice with an identical body
```

### What to look for

| What happened | What it means |
|---|---|
| Two jobs appeared | **that is correct behaviour. And that is the problem** |
| Only one appeared | something blocked it — find out what |

**[There are no idempotency keys](/guide/ht-rest-api).** Send it twice and **it
runs twice.** It was harmless here because the job only reads — but had it been an
email send, two emails would have gone out.

### So what do you do

The caller has to prevent it. Pick whichever fits your situation.

```
□ Before sending, query whether a job with the same instruction is already running
□ Generate a request key on your side and never resend a key you already sent
□ Retry only on a confirmed failure   <- a timeout is not a failure
```

**The third line causes the most incidents.** A slow response gets read as a
failure and resent, while the server is still happily processing the first one.

---

## Step 5 — Tidy up (5 min)

```
□ You cleaned up the practice jobs
□ You checked the token did not end up in a record (shell history included)
□ You wrote down the poll interval and your duplicate-prevention approach
```

---

## Self-check

```
□ You confirmed auth with a read call first
□ You confirmed REST and the screen show the same job
□ You saw two jobs appear from the same request twice  <- if not, back to step 4
□ You picked a way to prevent duplicates
```

---

## Check yourself

**1. Why call a read endpoint before creating a job?**

<details>
<summary>Answer</summary>

**To separate auth problems from request problems.** If the read works, the token
is fine, so any later error is in the request body.
</details>

**2. Why do two identical requests create two jobs?**

<details>
<summary>Answer</summary>

**There are no idempotency keys.** The server treats them as separate requests.
Deduplication has to happen on the calling side.
</details>

**3. What is wrong with retrying on a timeout?**

<details>
<summary>Answer</summary>

**A timeout may be a slow response, not a failure.** If the second request arrives
while the server is still processing the first, the same work runs twice.
</details>

---

Now open the door on the model side → [Getting models — downloading and running them](/guide/ht-local-models)
