---
title: "Manage Certificates"
description: "Use the X.509 Store Service to store generic certificates or VICAL entries, list what is already stored, and manage individual entries by full target path."
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/x509-store-service/manage-certificates
generated: 2026-07-20
---
# Manage Certificates

Use the X.509 Store Service to store generic certificates or VICAL entries, list what is already stored, and manage individual entries by full target path.

Service reference: [Swagger API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Service%20%7C%20X.509%20Certificate%20Store)

## Shared Path Parameters

- `orgID`: When performing operations within an organization, use the organization's Base URL or another valid host alias. For example, if your organization is named `test`, your default Base URL will be `test.enterprise-sandbox.waltid.dev` when using the sandbox environment.
- `target`: For `list` and `list-ids`, use the X.509 Store service path (`{organizationID}.{tenantID}.{x509StoreServiceID}`), for example `test.tenant1.x509-store-1`. For `add`, use the store path to generate a certificate ID automatically, or use a full child certificate path to choose the ID yourself, for example `test.tenant1.x509-store-1.base-001`. For `get`, `update`, and `delete`, use the full stored certificate path.

## List stored certificates

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates?limit=50&offset=0&sort=createdDateTime' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}'
```

**Query Parameters**

- `limit`: _Integer (optional)_ – Maximum number of entries to return. Defaults to `100`.
- `offset`: _Integer (optional)_ – Number of entries to skip. Defaults to `0`.
- `sort`: _String (optional)_ – One of `createdDateTime`, `createdDateTime+`, `createdDateTime-`, `updatedDateTime`, `updatedDateTime+`, `updatedDateTime-`.

Invalid values return `400 Bad Request` — see the [pagination reference](https://docs.walt.id/enterprise-stack/setup/configurations/config-files/pagination.md) for the full contract.

**Example Response**

```json
[
  {
    "_id": "test.tenant1.x509-store-1.base-001",
    "data": {
      "type": "base",
      "pem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----"
    }
  },
  {
    "_id": "test.tenant1.x509-store-1.vical-001",
    "data": {
      "type": "vical-entry",
      "pem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
      "complementaryMetadata": {
        "docType": ["org.iso.18013.5.1.mDL"],
        "certificateProfile": ["1.0.18013.5.1.7"]
      }
    }
  }
]
```

**Response Codes**

- `200` - Stored certificates retrieved successfully.

## List stored certificate IDs

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates/ids`

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates/ids?limit=50&offset=0' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}'
```

**Query Parameters**

- `limit`: _Integer (optional)_ – Maximum number of entries to return. Defaults to `100`.
- `offset`: _Integer (optional)_ – Number of entries to skip. Defaults to `0`.

`sort` is not supported on this endpoint. Invalid values return `400 Bad Request` — see the [pagination reference](https://docs.walt.id/enterprise-stack/setup/configurations/config-files/pagination.md) for the full contract.

**Example Response**

```json
[
  "test.tenant1.x509-store-1.base-001",
  "test.tenant1.x509-store-1.vical-001"
]
```

**Response Codes**

- `200` - Stored certificate IDs retrieved successfully.

## Add a base certificate

Use the store target to generate a certificate ID automatically. Use a full child certificate target, such as `test.tenant1.x509-store-1.base-001`, when you want to choose the stored certificate ID.

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "base",
  "certificatePem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----"
}'
```

**Body Parameters**

- `type`: Set to `base` to store a generic X.509 certificate entry.
- `certificatePem`: PEM-encoded X.509 certificate to store.

**Example Response**

```json
{
  "_id": "test.tenant1.x509-store-1.base-001",
  "data": {
    "type": "base",
    "pem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----"
  }
}
```

**Response Codes**

- `201` - Certificate stored successfully.

The stored certificate ID comes from the request target. When the target is the store itself, the service generates a UUID child ID.

## Add a VICAL entry

Use the store target to generate a certificate ID automatically. Use a full child certificate target, such as `test.tenant1.x509-store-1.vical-001`, when you want to choose the stored certificate ID.

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "vical-entry",
  "certificatePem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
  "complementaryMetadata": {
    "docType": ["org.iso.18013.5.1.mDL"],
    "certificateProfile": ["1.0.18013.5.1.7"]
  }
}'
```

**Body Parameters**

- `type`: Set to `vical-entry` to store an IACA certificate plus VICAL metadata.
- `certificatePem`: PEM-encoded IACA certificate to store.
- `complementaryMetadata.docType`: Required list of document types covered by the IACA certificate.
- `complementaryMetadata.certificateProfile`: Optional list of certificate-profile identifiers to store with the entry.

**Example Response**

```json
{
  "_id": "test.tenant1.x509-store-1.vical-001",
  "data": {
    "type": "vical-entry",
    "pem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
    "complementaryMetadata": {
      "docType": ["org.iso.18013.5.1.mDL"],
      "certificateProfile": ["1.0.18013.5.1.7"]
    }
  }
}
```

**Response Codes**

- `201` - VICAL entry stored successfully.

A `vical-entry` requires a valid IACA certificate and non-empty `complementaryMetadata.docType`. `certificateProfile`, when provided, must also be non-empty.

## Get a stored certificate

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}'
```

**Example Response**

```json
{
  "_id": "test.tenant1.x509-store-1.vical-001",
  "data": {
    "type": "vical-entry",
    "pem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
    "complementaryMetadata": {
      "docType": ["org.iso.18013.5.1.mDL"],
      "certificateProfile": ["1.0.18013.5.1.7"]
    }
  }
}
```

**Response Codes**

- `200` - Stored certificate retrieved successfully.

## Update a stored certificate

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'PUT' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "vical-entry",
  "certificatePem": "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----",
  "complementaryMetadata": {
    "docType": ["org.iso.18013.5.1.mDL"],
    "certificateProfile": ["1.0.18013.5.1.7"]
  }
}'
```

**Body Parameters**

- `type`: Use `base` to replace the stored entry with a generic certificate, or `vical-entry` to replace it with an IACA certificate plus VICAL metadata.
- `certificatePem`: PEM-encoded certificate that should replace the current stored payload.
- `complementaryMetadata`: Required when `type` is `vical-entry`.

The target identifies which stored certificate is updated. You can switch between `base` and `vical-entry` on update.

**Response Codes**

- `204` - Certificate updated successfully.

## Delete a stored certificate

**Option: CURL**

Endpoint: `/v1/{target}/x509-store-api/certificates`

```bash
curl -X 'DELETE' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-store-api/certificates' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}'
```

**Response Codes**

- `200` - Certificate deleted successfully.
