# REST API

Base URL: https://api.levr.ai/v1/
Authentication: Bearer — Portal API key

Reference index: https://docs.levr.ai/rest-api-reference/index.md
OpenAPI specification: https://docs.levr.ai/generated/openapi.json

## Make your first request

Ask a Portal administrator to create an API key for your integration. Save it when it is shown; you cannot retrieve it again.

Read the API root to confirm which Portal the key belongs to and which resources it can access:

```sh
curl --request GET \
  --url 'https://api.levr.ai/v1/' \
  --header "Authorization: Bearer $LEVR_API_KEY"
```

Store the key in a secret manager. Keep it out of browser code, logs, prompts, and source control.

Set `LEVR_API_KEY` in your shell to the saved Portal API key before copying the examples. API keys belong to one environment; a staging key cannot authenticate against production. File-transfer credentials returned by an upload or download operation are separate: use the credential named by that operation.

The [published OpenAPI download](/generated/openapi.json) is public and needs no API key. The API's `/v1/openapi.json` endpoint requires a Portal API key and describes the resources granted to that key. Use the documented resource paths or URLs returned by API reads; a documentation page URL is not an API endpoint.

## Choose your task

Read the resource guide for the work you want to do. Each guide links to the exact operations; you do not need to read the entire reference.

- [Bring businesses into your Portal](/rest-api-reference/businesses/): choose a Lead source and create a business.
- [Complete client intake](/rest-api-reference/client-intake-applications/): answer questions, attach documents, use Autofill, and submit.
- [Find funding recommendations](/guides/matchmaking/): complete a project's Criteria, calculate matches, and review results.
- [Create and manage deals](/rest-api-reference/deals/): create a Deal for your own Portal or a chosen recipient, then follow its progress.
- [Complete a Deal application](/rest-api-reference/deal-applications/): prepare an application for one recipient and submit it.
- [Receive updates](/rest-api-reference/webhooks/): configure and verify webhooks.

AI agents can start with [the Markdown reference index](/rest-api-reference/index.md), then fetch only the relevant resource and operation Markdown. OpenAPI defines the exact REST paths and schemas. Application questions come from the record's returned `contract_url`.

## Make reliable requests

Follow the headers and inputs on each operation page. Unsupported query parameters are rejected rather than silently ignored.

## Read every page

REST collections return `items`, `next_cursor`, and `previous_cursor`. Set `page_size` using the range documented for that operation. Defaults and limits can differ between collections.

For example, read a page of businesses:

```sh
curl --request GET \
  --url "https://api.levr.ai/v1/businesses/?page_size=5" \
  --header "Authorization: Bearer $LEVR_API_KEY"
```

If `next_cursor` is not null, assign that exact value to `NEXT_CURSOR` and request the same collection with the `cursor` query parameter. Encode it as a query value rather than editing or decoding it:

```sh
curl --get \
  --url "https://api.levr.ai/v1/businesses/" \
  --data-urlencode "page_size=5" \
  --data-urlencode "cursor=$NEXT_CURSOR" \
  --header "Authorization: Bearer $LEVR_API_KEY"
```

Repeat until `next_cursor` is null. Keep the resource, filters, ordering, and page size unchanged while paging. Start a fresh first-page request when those controls change. Cursors are opaque values scoped to their collection; never reuse one for another application or collection. For collections that support backward paging, pass a non-null `previous_cursor` as `cursor` to return to an earlier page. Answers, repeatable answer items, and answer files support forward paging only; their `previous_cursor` is always null.

## Retry safely

For a write requiring `If-Match`, read the resource first and send its complete `ETag`, including quotes. Use the new ETag after each write. A `412 precondition_failed` means the resource changed: read it again and reconcile your change before retrying.

For an operation requiring `Idempotency-Key`, use a new key for a new command. Reuse it only for an identical retry, with the same method, resource, payload, and precondition.

A `429` response includes `Retry-After`; wait at least that long. Other errors include a message and structured details identifying what needs attention. When contacting support, include the response's `Request-Id`, never your API key.
