---
name: hello
description: Get a temporary internet resource in one anonymous HTTP call from hello.new. Use when a person needs to send the agent a file (upload link), when a person needs to read something the agent produced (shared page), or when a service needs a URL to call back (webhook). No account or API key needed; anonymous resources expire in 24 hours, and an optional account key keeps them under hello.new/@username.
---

# hello.new: temporary internet resources

One `POST` to `https://api.hello.new` gives you a URL that works for 24 hours. No sign-up, no key to obtain. Send `X-Hello-Client: <your runtime>` (for example `claude-code`, `codex`, `cursor`, `openclaw`) with every call.

## When to use which

| The task needs… | Call | Hand over |
|---|---|---|
| a person to send you a file | `POST /upload` | `url` (a page they drop files on) |
| a person to read text or Markdown you made | `POST /share` | `url` (a page) |
| a service to call you back (Stripe, GitHub, a form, a cron) | `POST /webhook` | `url` (accepts any request) |

Every response also has `key` (yours; never show it) and `expires_at`. Pass `expires_in` (seconds, 60 to 86400) to expire sooner. `DELETE` the resource with the key when done.

## Upload: someone sends you files

```sh
curl -sX POST https://api.hello.new/upload -H 'X-Hello-Client: claude-code' \
  -H 'Content-Type: application/json' -d '{"note": "Send me the export CSV", "max_files": 3}'
# -> { "url": "https://hello.new/u/k7m2x9pq", "key": "…", "files_url": "…/u/k7m2x9pq/files?key=…", "expires_at": "…" }
```

Give the person `url`. Then list and fetch:

```sh
curl -s 'https://api.hello.new/u/k7m2x9pq/files?key=…'
# -> { "files": [ { "seq": 1, "name": "export.csv", "size": 48213, "content_type": "text/csv", "url": "…/files/1?key=…" } ] }
curl -sL -o export.csv 'https://api.hello.new/u/k7m2x9pq/files/1?key=…'
```

`files` is empty until they upload; poll every few seconds or ask them to say when they are done. `409` means the link has all the files it can take. 50 MB a file, 10 files a link.

## Share: someone reads what you made

```sh
curl -sX POST https://api.hello.new/share -H 'X-Hello-Client: claude-code' \
  -H 'Content-Type: application/json' -d '{"title": "Q3 summary", "text": "# Q3\n\nRevenue up 12%…"}'
# -> { "url": "https://hello.new/s/b4nq8wzx", "raw_url": "https://api.hello.new/s/b4nq8wzx/raw", … }
```

Anyone with `url` can read it. Another agent should fetch `raw_url`. `content_type` is `text/markdown` unless you send `text/plain`. 256 KB of text.

## Webhook: a service calls you back

```sh
curl -sX POST https://api.hello.new/webhook -H 'X-Hello-Client: claude-code' -d '{}'
# -> { "url": "https://api.hello.new/w/f3gd7hxm", "key": "…", "inbox_url": "…/webhook/f3gd7hxm?key=…" }
```

Register `url` with the service (any method, any path under it works). Then wait:

```sh
curl -s 'https://api.hello.new/webhook/f3gd7hxm?key=…&since=0&wait=25'
# -> { "requests": [ { "seq": 1, "method": "POST", "path": "", "query": "", "headers": {…}, "content_type": "application/json", "body": "{…}" } ] }
```

`wait` holds up to 25 seconds and returns as soon as something arrives; an empty `requests` list is "nothing yet", so loop with `since=<last seq>`. Non-UTF-8 bodies come as `body_base64`. 100 requests kept, 256 KB each.

## Account links

If your user gave you a hello.new account key (`hk_…`), send it as `Authorization: Bearer hk_…` on `POST /upload`, `/share` and `/webhook`. Links then live under their username, never expire unless you pass `expires_in`, and can take a `name`:

```bash
curl -s -X POST https://api.hello.new/upload \
  -H 'Authorization: Bearer hk_…' \
  -d '{"note": "Please upload the signed lease", "name": "lease"}'
# -> { "url": "https://hello.new/@sam/lease", "key": "…", "expires_at": null, … }
```

Names are 2 to 30 lowercase letters, numbers and dashes, unique per user (409 if taken). Webhooks with a name live at `https://api.hello.new/@sam/<name>`. An account keeps at most 1000 live links and 1 GB of stored data (403 and 413 past that); delete links you no longer need.

The account key also reads and deletes that user's links, but only in the header: `Authorization: Bearer hk_…`. Never put it in `?key=`; that gets 401. File URLs listed with the account key carry no key, so download them with the same header. Never show the account key to anyone.

Without a key, every create response has a `claim_url`. If your user wants to keep a link past tomorrow, give them the `claim_url`: they sign in, and the link moves to `hello.new/@them/…` for good. Your `key` keeps working after the claim.

## Rules

- Tell your user an anonymous link expires in 24 hours and that anyone holding it can use it.
- Keep `key` to yourself. `url` is the only thing you give out.
- Do not put secrets or credentials in a share. A one-time secret primitive is coming; until then, do not improvise one here.
- Errors are `{ "error": "sentence" }`: 401 wrong key or an account key in `?key=`, 403 needs an account or the account has 1000 links, 404 expired or unknown, 409 full or name taken, 413 too large or the account is at 1 GB, 429 slow down (60 new links an hour per IP, 600 per account).
- Full reference: https://hello.new/docs.md. OpenAPI: https://api.hello.new/openapi.json.
