> ## Documentation Index
> Fetch the complete documentation index at: https://hitspec.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Write and run your first API test in under a minute

> Write a plain-text .http file with requests, assertions, and captures, then run it with hitspec. A fast first API test you can read, diff, and commit.

<Steps>
  <Step title="Create a test file">
    Create a file called `api.http`:

    ```http api.http theme={null}
    @baseUrl = https://jsonplaceholder.typicode.com

    ### Get a post
    # @name getPost

    GET {{baseUrl}}/posts/1

    >>>
    expect status 200
    expect body.id == 1
    expect body.title exists
    <<<

    >>>capture
    authorId from body.userId
    <<<

    ### Create a post
    # @name createPost

    POST {{baseUrl}}/posts
    Content-Type: application/json

    {
      "title": "Hello hitspec",
      "body": "Testing made simple",
      "userId": 1
    }

    >>>
    expect status 201
    expect body.id exists
    <<<

    ### Get the post's author
    # @name getAuthor
    # @depends getPost

    GET {{baseUrl}}/users/{{getPost.authorId}}

    >>>
    expect status 200
    expect body.name exists
    expect body.email exists
    <<<
    ```

    This file defines three requests:

    1. **getPost** -- fetches a post, checks its fields, and captures the author's ID
    2. **createPost** -- creates a new post and checks the `201` response
    3. **getAuthor** -- runs after `getPost` and uses the captured `authorId` to fetch the author
  </Step>

  <Step title="Run the tests">
    ```bash theme={null}
    hitspec run api.http
    ```

    hitspec parses the file, executes each request in order (respecting dependencies), and evaluates all assertions.
  </Step>

  <Step title="See results">
    On success, you see a summary of passing tests:

    ```
      ✓ getPost (130ms)
      ✓ createPost (74ms)
      ✓ getAuthor (39ms)

    Tests: 3 passed, 3 total
    Time:  224ms
    ```

    If an assertion fails, hitspec shows exactly what went wrong:

    ```
      ✓ getPost (130ms)
      ✓ createPost (74ms)
      ✗ getAuthor (41ms)
        → status == (line 39)
          Expected: 200
          Actual:   404
          expected 200, got 404

    Tests: 2 passed, 1 failed, 3 total
    ```

    The output tells you which assertion failed, on which line, what value was expected, and what was actually returned.
  </Step>
</Steps>

## What Just Happened?

Let's break down the key concepts from this example:

**Variables** -- `@baseUrl` defines a reusable variable, referenced with `{{baseUrl}}`.

**Request separator** -- `###` marks the start of each request.

**Metadata** -- `# @name`, `# @depends` are directives that control behavior.

**Assertions** -- The `>>> ... <<<` block contains `expect` statements that validate the response.

**Captures** -- The `>>>capture ... <<<` block extracts values from responses (here, `authorId`) for use in later requests, referenced as `{{getPost.authorId}}`.

**Dependencies** -- `# @depends getPost` ensures `getAuthor` runs after `getPost`, so the captured `authorId` is available.

## Try it in studio

Prefer an interactive workflow? Open the same file in the terminal UI:

```bash theme={null}
hitspec studio api.http
```

Studio lets you edit, run, and inspect requests in a tabbed response viewer, with
dedicated screens for stress, mock, contract, record, history, and more -- all
keyboard-first. See the [Studio guide](/studio).

## Next Steps

<Columns cols={2}>
  <Card title="Installation" icon="download" href="/installation">
    Install hitspec via Homebrew, Go, or binary download.
  </Card>

  <Card title="Studio (Terminal UI)" icon="terminal" href="/studio">
    Edit, run, and inspect requests interactively in the terminal.
  </Card>

  <Card title="Editor Setup" icon="code" href="/editor-setup">
    Get syntax highlighting and completions in your editor.
  </Card>

  <Card title="Core Concepts" icon="book" href="/concepts/file-format">
    Learn the file format, variables, assertions, and captures.
  </Card>
</Columns>
