---
title: "Create an SII key"
method: POST
path: "/v1/sii/keys"
tags: ["SII Key"]
---

# Create an SII key

`POST /v1/sii/keys`

Stores a new SII credential for the caller. Cardda encrypts `password` and
`certificate_password` at rest; this is the only entry point that accepts them
in clear text. On creation Cardda runs a synchronous company sync against the
SII — on success the key flips to `approved` and its managed companies are
resolved; if the SII rejects the credentials the key ends up `declined`.

Company users must set `user_id` to their own Firebase uid, otherwise the
request is rejected with `401`.

## Parameters

- `#/paths/~1v1~1sii~1keys/get/parameters/0` — unresolved $ref

## Request body

- SiiKeyCreate
  - `rut` string, required — Tax id (RUT) the SII certificate belongs to. Digits plus verifier digit, no dots (e.g. `761234567` or `12345678K`). Must be unique across all SII keys; a duplicate is rejected with `422`.
  - `password` string, required — SII portal password for the RUT. Stored encrypted at rest and never returned by any read endpoint.
  - `certificate_password` string — Password of the digital certificate (`.pfx`/`.p12`) used to sign electronic documents. Optional at creation, but required before the key can issue (`can_issue?`). Stored encrypted; never returned by read endpoints.
  - `user_id` string, required — Firebase user id that owns the credential. **Required**. Create authorization runs before the record is saved and only passes when `user_id` matches the caller (or the caller is Cardda staff). A company user who omits `user_id` (or sets it to another user) is therefore rejected with `401` before any validation runs. For a Cardda staff caller, authorization passes and a missing `user_id` then fails the mandatory `user` association with `{ "message": "Validation failed: User must exist" }` (`422`).

## Response `201`

The created SII key. `status` is `approved` if the synchronous company
sync succeeded, otherwise `pending`/`declined`.

- SiiKey
  - `id` string, uuid, required — UUID of the SII key.
  - `rut` string, required — Tax id (RUT) the certificate belongs to, stored as bare digits plus the verifier digit (e.g. `761234567` or `12345678K`). Unique across all SII keys.
  - `user_id` string, nullable — Firebase user id of the person who provided the credential.
  - `status` 'approved' | 'pending' | 'canceled' | 'declined', required — Lifecycle status of the credential. | Value | Meaning | | ----- | ------- | | `pending` | Just created; Cardda has not yet validated it against the SII. | | `approved` | Validated; the key can sync companies and invoices. | | `declined` | The SII rejected the credentials (`auth/wrong-credentials`). | | `canceled` | The credential was disabled. |
  - `issuer_phone` integer, nullable — Phone number registered for the issuer, when captured.
  - `last_synced_at` string, date-time, nullable — Timestamp of the last successful invoice/company sync.
  - `can_issue` boolean — Whether the key can issue electronic documents — true when `status` is `approved` **and** a certificate password is present. **Note:** this field is serialized with a trailing question mark in the JSON response (`can_issue?`).
  - `company_ids` string[] — UUIDs of the companies this key manages (resolved through the SII managers join). Present on the list and detail responses; omitted from the update response.
  - `created_at` string, date-time — When the key was created in Cardda.
  - `updated_at` string, date-time — When the key was last updated.

## Other responses

- `401` — Unauthorized — missing/invalid token, or a non-staff caller tried to create a key for a different (or missing) `user_id`. Authorization runs before the save and is by ownership (`user_id` must match the caller, unless the caller is Cardda staff); the `company-id` header plays no part in create authorization. Empty body.
- `422` — Unprocessable entity — validation failed (`{ "message": "Validation failed: ..." }`), e.g. missing/blank `password`, missing/invalid `rut`, or a RUT that already has an SII key (the `rut` unique index). A missing `user_id` reaches this validation (`{ "message": "Validation failed: User must exist" }`) **only** for Cardda staff callers; a company user who omits `user_id` is rejected earlier with `401` (see above), because authorization runs before the save.

---

[API](https://skmtc.dev/cardda/apis/banking-api.md) · [All operations](https://skmtc.dev/cardda/apis/banking-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/cardda/banking-api/revisions/ff1aeb3fda8b/schema)
