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

# Authentication

> API keys: how to create them, their permissions, how long they are valid, and how to revoke them.

Each request to the API carries a key in the header `Authorization`:

```http theme={null}
Authorization: Bearer 12|hsr_live_9fQ2kX...
Accept: application/json
```

The only exception is the vocabulary, `GET /schema`, which is public and does not require a key.

## What a Key Does

A key **acts on behalf of the account that created it**. It can do exactly what the account can do in the portal, with the same limitations:

* the listings created via the API belong to the account, as if you had added them through the form;
* if you are a member of an agency, the listing gets the agency, just like when you publish from the account;
* if you are an owner or admin of the agency, you can see and manage through the API the listings of your colleagues;
* the name and contact email of the listing are those of the account, and the phone number is the one from the account unless you send another one in `contact_phone`.

## How to Create a Key

<Steps>
  <Step title="Open Settings → API">
    In production, at [housera.ro/setari/api](https://housera.ro/setari/api). In sandbox, at `https://staging.housera.ro/setari/api`. You need an account with a confirmed email.
  </Step>

  <Step title="Choose the name, permissions, and validity">
    The name helps you recognize the key later (for example `crm-productie`). You only check the permissions you need.
  </Step>

  <Step title="Copy the key">
    The key is shown **only once**, immediately after creation. Housera does not store it in plaintext, so it cannot show it to you again. If you lose it, you revoke it and create another one.
  </Step>
</Steps>

## Permissions

| Permission | What it Allows |
| - | - |
| `listings:read` | You read your listings (`GET /account/listings`, `GET /account/listings/{code}`, `GET /account/listings/ref/{ref}`) and events (`GET /events`). |
| `listings:write` | You create, validate, edit and delete listings, mark them as sold, put them on hold, or reactivate them. |
| `media:write` | You prepare uploads (`POST /uploads`) and set the photos of a listing (`PUT /listings/{code}/photos`). |

A complete integration requires all three. For a panel that only displays the listings, `listings:read` is sufficient.

## Prefixes

The prefix immediately tells you on what environment a key operates:

| Prefix | Environment |
| - | - |
| `hsr_test_` | Sandbox (`https://staging.housera.ro/api/v1`) |
| `hsr_live_` | Production (`https://housera.ro/api/v1`) |

The complete key has the form `<id>|hsr_live_<secret>`. Send the entire string, with the id and the vertical bar.

<Tip>
  Fixed prefixes make keys easily recognizable by secret scanners. If a key accidentally ends up in a public code repository, revoke it immediately.
</Tip>

## Validity

Each key expires. Upon creation, you choose **30, 90 or 365 days**. The expiration date is visible on the Settings → API page, next to the creation date and the last usage date.

When a key expires, requests receive `401`. To avoid interruptions, create the new key before the deadline, put it in your system, and then revoke the old one.

An account has **at most 10 keys** at the same time: enough for one key per integration, with room for rotation.

## Revocation

From Settings → API, you revoke any key with one click. The effect is immediate: the next request with that key receives `401`. Key creation and revocation appear in the activity log of the account.

## Authentication Errors

| Status | When |
| - | - |
| `401 Unauthorized` | Missing header `Authorization`, the key is incorrect, expired, or revoked, or the account is no longer active. |
| `403 Forbidden` | The key is valid but does not have the permission required by the endpoint (for example `PUT /listings/{code}/photos` without `media:write`). |

The body is a “problem details” object (RFC 9457), with a stable `code` that you can test in your code:

```json theme={null}
{
  "type": "https://housera.ro/problems/unauthenticated",
  "title": "Lipsește cheia API sau nu mai e valabilă.",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Lipsește cheia API sau nu mai e valabilă."
}
```

At `403`, `code` is `missing_ability` when the key lacks the required permission and `forbidden` otherwise.

<Warning>
  Never put the key in an application running in the user's browser or on their phone. Anyone who sees it there can publish on behalf of your account. The key only resides on your server.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.