
# API-avainten rajapinta

Näiden päätepisteiden avulla voit hallita tilisi API-avaimia koodin kautta. Ne kaikki toimivat vain kutsuvan tilin omien avainten osalta.

Avaimia on kahta tyyppiä, ja ne sijaitsevat eri poluilla:

- **Pääavaimesi** — yksittäinen täyden käyttöoikeuden avain kohdassa **Asetukset → Integraatiot → API-avain**. Voit tarkastella sen peitettyä esikatselua, tarkistaa nopeusrajoitusten käytön, vaihtaa avaimen tai mitätöidä sen. Nämä ovat alla olevia `/api-keys/current`-, `/api-keys/rotate`- ja `/api-keys/usage`-päätepisteitä.
- **Rajoitetut avaimet (Scoped keys)** — ylimääräisiä, nimettyjä avaimia, joita luot tiettyä tehtävää varten. Jokainen niistä on rajoitettu vain valitsemiisi API-osiin. Nämä ovat [rajoitettujen avainten](#scoped-keys) alla olevia `/api-keys`- ja `/api-keys/{id}`-päätepisteitä. Pääavaimesi ei muutu, kun luot tällaisen avaimen; olemassa olevat integraatiot toimivat edelleen ennallaan.

Kaikki alla olevat polut ovat suhteessa rajapinnan perus-URL-osoitteeseen:

```
https://api.youraiconnector.com/v1
```

Jokainen pyyntö on todennettava. Katso kohdasta [Todennus](authentication.md) neljä hyväksyttyä menetelmää. Tässä olevissa esimerkeissä käytetään `X-API-Key`-otsikkoa (ja yhtä kyselyparametrimuotoa cURL-kutsulle).

> **Lue tämä ensin.** Avaimen vaihtaminen tai mitätöinti astuu voimaan **välittömästi**. Heti kun kutsu onnistuu, vanha avain lakkaa toimimasta – jokainen sitä käyttävä integraatio alkaa saada `401`-virheitä. Suunnittele tämä: vaihda avain huoltoikkunan aikana ja päivitä kaikki integraatiosi välittömästi.

---

## Hae nykyisen avaimen metatiedot

Palauttaa aktiivisen avaimesi: koko avain kohdassa `api_key`, kun siitä on olemassa noudettava kopio, peitetty esikatselu (ensimmäiset 4 ja viimeiset 4 merkkiä) sekä mahdollisuuksien mukaan sen luontipäivämäärä. `api_key` on `null` avaimille, jotka on luotu ennen kuin noudettavia kopioita säilytettiin — kierrätä avain kerran, niin uusi avain voidaan näyttää uudelleen myöhemmin.

`GET /api-keys/current`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/api-keys/current?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/api-keys/current", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/api-keys/current",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "api_key": "abcdEFGH1234ijkl5678MNOP9012qrst",
  "api_key_masked": "abcd...qrst",
  "created_at": "2026-06-01T10:00:00.000Z"
}
```

Jos tilillä ei ole API-avainta, vastaus on `404` ja sisältää `{ "success": false, "error": "No API key found for this account" }`.

---

## Hae nopeusrajoituksen käyttö

Palauttaa nykyisen ikkunan nopeusrajoituksen käytön: pyyntörajan per ikkuna, tähän mennessä laskettujen pyyntöjen määrän, jäljellä olevien pyyntöjen määrän sekä ikkunan nollautumisajan. Käytä tätä asiakaspuolen rajoitusten (throttling) rakentamiseen, jotta integraatiosi hidastaa toimintaansa ennen kuin se kohtaa `429`-vastauksia.

`GET /api-keys/usage`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/api-keys/usage" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/api-keys/usage", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/api-keys/usage",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "usage": {
    "limit": 300,
    "window_seconds": 60,
    "used": 37,
    "remaining": 263,
    "window_resets_at": "2026-06-09T12:01:00.000Z"
  }
}
```

Jos nykyisessä ikkunassa ei ole vielä kirjattu yhtään pyyntöä, käytöksi ilmoitetaan nolla ja vastaus sisältää `note`-kentän, joka selittää syyn.

---

## Vaihda avain

Luo uuden API-avaimen ja mitätöi edellisen samassa vaiheessa. Käytä tätä, jos epäilet avaimen vuotaneen, tai osana säännöllistä tunnusten vaihtokäytäntöä.

`POST /api-keys/rotate`

> **Uusi avain näytetään vain kerran.** Se palautetaan tässä vastauksessa, eikä sitä voi hakea kokonaisuudessaan myöhemmin – tallenna se turvallisesti heti, kun saat sen. Edellinen avain lakkaa toimimasta heti, kun tämä kutsu onnistuu, joten päivitä jokainen integraatio, joka käytti sitä.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/api-keys/rotate?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/api-keys/rotate", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
// Save data.api_key now — it will not be shown again.
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/api-keys/rotate",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
# Save data["api_key"] now — it will not be shown again.
```

**Vastaus**

```json
{
  "success": true,
  "api_key": "abcdEFGH1234ijkl5678MNOP9012qrst",
  "message": "API key rotated. The previous key is no longer valid. Store this key now — it will not be shown again."
}
```

---

## Peruuta avain

Poistaa pysyvästi tilisi API-avaimen. Peruutus on välitön: jokainen seuraava pyyntö, joka käyttää peruutettua avainta – mukaan lukien integraatiot, kuten Make, Zapier tai mukautetut skriptit – hylätään virheellä `401`. Jos haluat palauttaa API-yhteyden myöhemmin, luo uusi avain tilisi asetuksista ollessasi kirjautuneena sovellukseen.

`DELETE /api-keys/current`

> **Toimintoa ei voi kumota.** Toisin kuin avaimen vaihto, peruutus ei anna sinulle korvaavaa avainta. Peruuta avain vain, kun aiot lopettaa API-yhteyden (esimerkiksi vuotanut avain, jota et voi heti korvata).

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/api-keys/current" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/api-keys/current", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/api-keys/current",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Vastaus**

```json
{
  "success": true,
  "revoked": true,
  "message": "API key revoked. All requests using it will be rejected immediately."
}
```

Jos tilillä ei ole peruutettavaa avainta, vastauksena on `404`.

---

## Rajoitetut avaimet

Rajoitettu avain on ylimääräinen API-avain, jonka luot yhtä tiettyä tehtävää varten ja jolla on vain kyseiseen tehtävään tarvittavat käyttöoikeudet. Tyypillinen tilanne: haluat yhdistää asiakaskohtaisen hallintapaneelin, raportointityökalun tai sisäisen skriptin tiliisi ilman, että annat avainta, jolla voisi myös lähettää viestejä, muuttaa tekoälyagenttejasi tai ostaa puhelinnumeroita.

Rajoitus seuraa itse avainta, joten sen haltija voi tehdä vain sen, minkä sallit avainta luodessasi.

**Mitä voit rajoittaa**

| Kenttä | Mitä se tarkoittaa |
|---|---|
| `read_only` | `true` (oletus) tarkoittaa, että vain lukupyynnöt ovat sallittuja. Kaikki luonti-, päivitys- tai poistopyynnöt hylätään. |
| `tags` | Luettelo API-osioista, joita avain saa käyttää. Käytä samoja osioiden nimiä, jotka näet näissä ohjeissa ja [API-selaimessa](reference.md) — `Analytics`, `Campaigns`, `Contacts`, `Messages`, `Appointments` jne. Tyhjä luettelo tarkoittaa kaikkia osioita. |
| `sub_account_ids` | Mitä hallinnoituja tilejä avain saa käyttää. Tyhjä tarkoittaa vain omaa tiliäsi; `["*"]` tarkoittaa mitä tahansa tiliä, jota hallinnoit. Omistusoikeus tarkistetaan silti jokaisen pyynnön yhteydessä. |
| `rate_limit_per_min` | Pyyntöjen määrä minuutissa tälle avaimelle. Se lasketaan omassa budjetissaan, joten se ei kuluta muiden integraatioidesi kiintiötä. Oletusarvo on `60`, eikä sitä voi asettaa arvoa `300` suuremmaksi. |

Voit myös asettaa avaimelle `expires_at`-päivämäärän (ISO 8601, ja sen on oltava tulevaisuudessa). Tämän hetken jälkeen avain lakkaa toimimasta. Jos jätät tämän määrittämättä, avain ei vanhene koskaan, ellet itse mitätöi sitä.

> **Kieltäminen on oletusarvo.** Jos pyyntö ylittää avaimen sallitut rajat, se hylätään sen sijaan, että se sallittaisiin: kirjoituspyyntö vain luku -avaimella palauttaa `403` ja `error_code: "key_read_only"`, ja kaikki avaimen sallittujen osioiden ulkopuolelle jäävä palauttaa `403` ja `error_code: "key_scope_denied"`. Jos rajoitettu avain saa odottamattoman `403`-virheen, kutsumasi päätepiste ei yksinkertaisesti kuulu sen laajuuteen — laajenna avaimen oikeuksia tai käytä pääavaintasi.

> **Vain tilin omistaja hallinnoi avaimia.** Nämä neljä päätepistettä vaativat pääavaimesi tai omistajan istunnon sovelluksessa. Rajoitettu avain ei voi koskaan listata, luoda, muokata tai mitätöidä avaimia — mukaan lukien itseään — joten rajoitettua avainta ei voi koskaan käyttää laajemman avaimen luomiseen. Yritys palauttaa `403` ja `error_code: "key_scope_denied"`. Samasta syystä `API Keys` ei ole osio, jonka voit myöntää: sen pyytäminen palauttaa `400` ja `error_code: "invalid_scopes"`.

### Listaa rajoitetut avaimet

Palauttaa tilin rajoitetut avaimet uusimmasta alkaen (enintään 200), mukaan lukien mitätöidyt, jotta näet, mikä on poistettu ja milloin. Vain peitetyt esikatselut palautetaan — rajoitetun avaimen arvo näytetään vain kerran luontihetkellä, eikä sitä voi hakea sen jälkeen.

`GET /api-keys`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/api-keys" \
  -H "X-API-Key: YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "api_keys": [
    {
      "id": "key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a",
      "label": "Client dashboard - Acme",
      "key_preview": "abcd...qrst",
      "scopes": {
        "read_only": true,
        "tags": ["Analytics"],
        "sub_account_ids": [],
        "rate_limit_per_min": 60
      },
      "expires_at": null,
      "last_used_at": "2026-08-20T14:03:00.000Z",
      "created_at": "2026-08-14T09:12:00.000Z",
      "revoked_at": null,
      "revoked": false
    }
  ]
}
```

### Luo rajoitettu avain

Luo uuden rajatun avaimen ja palauttaa sen arvon **kerran**.

`POST /api-keys`

> **Avain näytetään vain kerran.** Se on tässä vastauksessa eikä missään muualla, koskaan — sitä ei voi hakea jälkikäteen. Tallenna se heti, kun vastaanotat sen. Jos kadotat sen, peruuta se ja luo uusi.

**Runkokentät** — kaikki valinnaisia:

| Kenttä | Tyyppi | Huomautuksia |
|---|---|---|
| `label` | string | Oma nimesi avaimelle, näkyy luettelossa ja asetuksissa. |
| `scopes` | object | Neljä kenttää yllä olevassa taulukossa. Jätä koko objekti pois, niin saat turvallisen oletuksen: vain luku, rajoitettu kohteeseen `Analytics`, vain oma tilisi, 60 pyyntöä minuutissa. |
| `expires_at` | ISO 8601 -päivämäärä | Valinnainen vanhenemispäivä, on oltava tulevaisuudessa. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/api-keys" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Client dashboard - Acme",
    "scopes": {
      "read_only": true,
      "tags": ["Analytics"],
      "sub_account_ids": [],
      "rate_limit_per_min": 60
    }
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/api-keys", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    label: "Client dashboard - Acme",
    scopes: { read_only: true, tags: ["Analytics"] },
  }),
});
const data = await res.json();
// Save data.api_key now — it will not be shown again.
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/api-keys",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "label": "Client dashboard - Acme",
        "scopes": {"read_only": True, "tags": ["Analytics"]},
    },
)
data = res.json()
# Save data["api_key"] now — it will not be shown again.
```

**Vastaus** — `201 Created`

```json
{
  "success": true,
  "api_key": "abcdEFGH1234ijkl5678MNOP9012qrst",
  "key": {
    "id": "key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a",
    "label": "Client dashboard - Acme",
    "key_preview": "abcd...qrst",
    "scopes": {
      "read_only": true,
      "tags": ["Analytics"],
      "sub_account_ids": [],
      "rate_limit_per_min": 60
    },
    "expires_at": null,
    "revoked": false
  },
  "message": "Store this key now — it is shown once and cannot be retrieved again."
}
```

Muutama yksityiskohta, jotka on hyvä tietää, kun rakennat tätä vasten:

- **`scopes`-kohdan jättäminen pois ei ole sama asia kuin tyhjän `tags`-luettelon lähettäminen.** Jätä `scopes` kokonaan pois, niin saat turvallisen oletuksen (vain luku, vain `Analytics`). Lähetä `"tags": []` tarkoituksella, niin avain voi käyttää jokaista osiota — se tulkitaan tietoiseksi pyynnöksi rajoittamattomasta avaimesta.
- **`read_only` pysyy `true`-tilassa, ellet nimenomaisesti lähetä `false`-arvoa.** Kirjoitusvirhe tai puuttuva lippu ei voi koskaan vahingossa tuottaa avainta, jolla on kirjoitusoikeus.

### Rajatun avaimen päivittäminen

Muuttaa avaimen nimeä, laajuuksia ja/tai vanhenemispäivää. Lähetä mikä tahansa yhdistelmä näistä kolmesta; jos et lähetä mitään, palautetaan `400`.

`PATCH /api-keys/{id}`

`{id}` on avaimen `id` luettelosta (arvo `key_...`), ei koskaan itse avain.

> **Laajuudet korvataan, ei yhdistetä.** Kaikki, mitä lähetät, muodostaa avaimen täydellisen käyttöoikeusjoukon. Tämä on harkittua: avaimen rajoittaminen ei voi koskaan jättää vanhaa, laajempaa käyttöoikeutta voimaan huomaamatta. Lähetä aina koko `scopes`-objekti, jonka haluat, älä vain kenttää, jota olet muuttamassa.

Avaimen arvo ei koskaan muutu. Rajatulle avaimelle ei ole olemassa paikallista vaihtoa — jos haluat vaihtaa avaimen, luo uusi avain ja peruuta vanha, jotta tunnistetiedon käyttöoikeudet eivät voi koskaan muuttua integraatiossa, joka sitä vielä käyttää.

**cURL**

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/api-keys/key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Client dashboard - Acme (read-only)",
    "scopes": {
      "read_only": true,
      "tags": ["Analytics", "Campaigns"],
      "sub_account_ids": [],
      "rate_limit_per_min": 30
    }
  }'
```

**Vastaus**

```json
{
  "success": true,
  "key": {
    "id": "key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a",
    "label": "Client dashboard - Acme (read-only)",
    "key_preview": "abcd...qrst",
    "scopes": {
      "read_only": true,
      "tags": ["Analytics", "Campaigns"],
      "sub_account_ids": [],
      "rate_limit_per_min": 30
    },
    "expires_at": null,
    "last_used_at": "2026-08-20T14:03:00.000Z",
    "created_at": "2026-08-14T09:12:00.000Z",
    "revoked_at": null,
    "revoked": false
  }
}
```

Jos tililläsi ei ole avainta kyseisellä tunnisteella, vastauksena on `404`.

### Rajatun avaimen mitätöinti

Mitätöinti tapahtuu välittömästi: seuraava kyseistä avainta käyttävä pyyntö hylätään virheellä `401`. Pääavaimesi ja kaikki muut rajatut avaimet säilyvät ennallaan.

`DELETE /api-keys/{id}`

Avain pysyy luettelossasi merkittynä tilalla `"revoked": true`, joten säilytät tiedon siitä, mitä avaimia on ollut olemassa ja mihin ne ovat päässeet käsiksi. Jo mitätöidyn avaimen mitätöiminen onnistuu, mutta se ei muuta mitään.

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/api-keys/key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a" \
  -H "X-API-Key: YOUR_API_KEY"
```

**Vastaus**

```json
{
  "success": true,
  "revoked": true,
  "id": "key_9f2c1a7b4d6e8f0a1b2c3d4e5f60718a",
  "message": "API key revoked. All requests using it will be rejected immediately."
}
```

---

## API-avainten API-virheet

API-avainten päätepisteet palauttavat vakioidun virhekuoren:

```json
{
  "success": false,
  "error": "No API key found for this account"
}
```

API-avainten päätepisteessä puuttuva tai virheellinen avain palauttaa `401` ja tili, jolla ei ole tallennettua avainta, palauttaa `404`. Jaetut koodit, joita jokainen päätepiste voi palauttaa — `400`, `403` (tilauksesi ei sisällä API-käyttöoikeutta), `429` (nopeusrajoitus) ja `500` — on lueteltu uudelleenyritysohjeiden kera kohdassa [Virheet ja sivutus](errors-and-pagination.md).

Rajatun avaimen päätepisteet lisäävät muutamia nimettyjä koodeja `error_code`-kenttään, jotta voit erottaa tapaukset toisistaan:

| `error_code` | Tila | Mitä tapahtui |
|---|---|---|
| `key_read_only` | `403` | Vain luku -oikeuksilla varustettu avain yritti kirjoittaa. |
| `key_scope_denied` | `403` | Avainta ei sallita kyseisessä päätepisteessä tai hallinnoidussa tilissä — tai rajattu avain yritti hallinnoida API-avaimia, mikä ei ole koskaan sallittua. |
| `invalid_scopes` | `400` | Pyydetyt laajuudet sisälsivät `API Keys`-osion. Avaimet eivät voi hallinnoida avaimia. |
| `404` | `404` | Tililläsi ei ole avainta kyseisellä tunnisteella. |

---

## Seuraavat vaiheet

- [Todennus](authentication.md) — neljä tapaa todentaa pyyntö ja miten avainten laajuudet (scopes) toteutetaan.
- [Virheet ja nopeusrajoitukset](errors-and-pagination.md) — tilakoodit ja 300 pyyntöä/minuutti -rajoitus.
