# Console API Reference

## Introduction

The Console Sources API creates and inspects Console [sources](/docs/console/sources) programmatically. A source captures HTTP requests so you can read them back; because a Console source is free and disposable, its ingest URL is typically used as a test URL.

> The Console Sources API is in early beta (`0.1.0`). The contract may change.

Everything lives on the `console.hookdeck.com` host. Creation and ingestion are proxied to Hookdeck server-side, so you only ever handle `console.hookdeck.com` URLs.

Base URL: `https://console.hookdeck.com`

A source has two addresses, and the create response names both:

* `ingest_url` (`console.hookdeck.com/e/<id>`) captures requests.
* `inspect_url` (`console.hookdeck.com/<id>`) is where you read them.

The [Hookdeck REST API](/docs/api) at `api.hookdeck.com` is a separate API with its own authentication, resources, and documentation. Nothing here applies to it.

The OpenAPI description is published at [console.hookdeck.com/openapi.json](https://console.hookdeck.com/openapi.json).

## Authentication

There is none. Every endpoint is public, and creating a source requires no account.

Access is granted by knowing a source's ID. Anyone with the ID can send requests to it, read the requests it captured, and open it in the Console. That's what makes a test URL shareable with a teammate.

That makes the ID a capability, not a secret. Don't send anything through a Console source you wouldn't want anyone holding the link to read. For authenticated access control, use an [Event Gateway](/docs/hookdeck-basics) project, which needs a Hookdeck account.

### The `cli_key` is not a bearer token

The create response includes a `cli_key`. It exists for the [Hookdeck CLI](/docs/cli), which uses it to forward captured requests to your machine. It is not an API credential: passing it as `Authorization: Bearer` will not authenticate a request to this API or to `api.hookdeck.com`.

```bash
curl -X POST "https://console.hookdeck.com/"

```

## Rate limits

Creating sources is rate limited.

| Endpoint | Limit |
| --- | --- |
| `POST /` | 60 requests per minute |
| `GET /new` | 10 requests per minute |

Exceeding a limit returns `429 Too Many Requests` with a `Retry-After` header giving the seconds to wait.

Limits apply per client IP by default. If you [replay the session cookie](#sessions), they track that session instead of the IP it's called from.

Ingestion to `/e/{id}` is not covered by these limits. It's subject to the platform [limits](/docs/limits).

```text
HTTP/1.1 429 Too Many Requests
Retry-After: 30

```

## Errors

Errors use conventional HTTP status codes.

| Status | Meaning |
| --- | --- |
| `404` | No test URL with that ID. |
| `422` | The requested source `type` is unsupported, or requires authentication and so can't be used in the Console. |
| `429` | Creation rate limit exceeded. Retry after the interval in `Retry-After`. |

A `422` response carries the code, the status, and a `data` array naming what was rejected.

Ingestion is the exception: a request to `/e/{id}` returns whatever response the source is configured to return, `200` by default. That response describes the source, not the state of this API.

```json
{
  "code": "unprocessable_entity",
  "status": 422,
  "data": [
    {
      "message": "Source type is not supported",
      "path": ["type"]
    }
  ]
}

```

## Sessions

The first unauthenticated create returns a session cookie on `.hookdeck.com`, with `SameSite=Strict` and a fixed 90-day lifetime that doesn't slide with use.

Replaying that cookie on later creates keeps those sources together, so they show up in the same source list. It's optional, and most callers won't need it. Save it on the first create with `-c` and send it back with `-b`.

Without it, each create stands alone. The sources still work identically; they just aren't listed together.

### Creating from a browser

`GET /new` creates a source and redirects to it. The create happens client-side, so it only works in a browser that runs JavaScript. A non-browser client gets the app shell and creates nothing.

Prefer `POST /` for anything programmatic. A link that creates on `GET` is a convenience, not an API.

```bash
# Save the cookie on the first create
curl -sS -c cookies.txt -X POST "https://console.hookdeck.com/"

# Replay it, so both sources are listed together
curl -sS -b cookies.txt -X POST "https://console.hookdeck.com/"

```

## API Resources

### Sources

* [Sources](/docs/console/api/sources.md)
  * [Sources](/docs/console/api/sources.md#sources)

### Ingestion

* [Ingestion](/docs/console/api/ingestion.md)
  * [Ingestion](/docs/console/api/ingestion.md#ingestion)

### Inspection

* [Inspection](/docs/console/api/inspection.md)
  * [Inspection](/docs/console/api/inspection.md#inspection)
