|
| 1 | +--- |
| 2 | +title: "Certificate API" |
| 3 | +linktitle: "Certificate API" |
| 4 | +url: /apidocs-mxsdk/apidocs/certificate-api/ |
| 5 | +weight: 50 |
| 6 | +description: "Describes how company admins can manage central certificates programmatically using the Certificate API, including listing, creating, updating, replacing, and deleting certificates." |
| 7 | +restapi: true |
| 8 | +--- |
| 9 | + |
| 10 | +## Introduction |
| 11 | + |
| 12 | +The Certificate API allows company admins to manage [landscape-wide (central) certificates](/developerportal/deploy/certificates/centralized-certificates/) via API. These certificates are used to configure custom domains on Mendix Cloud and can also be managed via [Certificate Management](/control-center/certificate-management/) in Control Center. |
| 13 | + |
| 14 | +{{% alert color="info" %}} |
| 15 | +The Certificate API does not manage local or app-level certificates. [App-level certificates](/developerportal/deploy/application-level-certificates/) are configured via Cloud Portal. |
| 16 | +{{% /alert %}} |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +To use the Certificate API, you must: |
| 21 | + |
| 22 | +* Be a company admin |
| 23 | +* Have a Mendix Personal Access Token (PAT) with the `mx:deployment:write` scope |
| 24 | + |
| 25 | +For information on creating a PAT, see [Personal Access Tokens](/mendix-profile/user-settings/#pat). |
| 26 | + |
| 27 | +## Capabilities |
| 28 | + |
| 29 | +The Certificate API lets you manage the central certificates owned by your company: |
| 30 | + |
| 31 | +| Capability | Method and Path | |
| 32 | +| --- | --- | |
| 33 | +| List certificates | `GET /v1/certificates` | |
| 34 | +| Create a certificate | `POST /v1/certificates` | |
| 35 | +| Update a certificate | `PATCH /v1/certificates/{certificateId}` | |
| 36 | +| Replace a certificate | `PUT /v1/certificates/{certificateId}/replacement` | |
| 37 | +| Delete a certificate | `DELETE /v1/certificates/{certificateId}` | |
| 38 | + |
| 39 | +All endpoints operate only on central certificates. Private key material, certificate PEM data, and internal identifiers are never returned in any response. |
| 40 | + |
| 41 | +## Base URL |
| 42 | + |
| 43 | +``` |
| 44 | +https://api.home.mendix.com/ |
| 45 | +``` |
| 46 | + |
| 47 | +## Authentication |
| 48 | + |
| 49 | +All requests must include your PAT in the `Authorization` header: |
| 50 | + |
| 51 | +``` |
| 52 | +Authorization: mxToken <PAT> |
| 53 | +``` |
| 54 | + |
| 55 | +The company that a request operates on is derived automatically from the authenticated token and you do not pass a company identifier. Every operation is scoped to and restricted to the certificates owned by that company. |
| 56 | + |
| 57 | +## Certificate Object |
| 58 | + |
| 59 | +Successful responses return a certificate object with the following structure: |
| 60 | + |
| 61 | +```json |
| 62 | +{ |
| 63 | + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", |
| 64 | + "description": "Wildcard cert for example.com", |
| 65 | + "validFrom": "2026-01-01T00:00:00Z", |
| 66 | + "validTill": "2027-01-01T00:00:00Z", |
| 67 | + "createdAt": "2026-01-02T09:15:00Z", |
| 68 | + "updatedAt": "2026-01-02T09:15:00Z", |
| 69 | + "status": "VALID", |
| 70 | + "inUse": true, |
| 71 | + "linkedFqdnsCount": 2 |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +| Field | Type | Description | |
| 76 | +| --- | --- | --- | |
| 77 | +| `id` | string (UUID) | Unique certificate identifier | |
| 78 | +| `description` | string | Free-text description (auto-generated from the certificate's subject/SAN if not supplied) | |
| 79 | +| `validFrom` | string (RFC3339) | Certificate validity start | |
| 80 | +| `validTill` | string (RFC3339) | Certificate validity end | |
| 81 | +| `createdAt` | string (RFC3339) | When the certificate was created | |
| 82 | +| `updatedAt` | string (RFC3339) | When the certificate was last modified | |
| 83 | +| `status` | string enum | One of `UPCOMING`, `VALID`, `EXPIRES SOON`, `EXPIRED`. Computed from validity dates; `EXPIRES SOON` applies within 15 days of expiry | |
| 84 | +| `inUse` | boolean | `true` if the certificate is linked to one or more custom domains | |
| 85 | +| `linkedFqdnsCount` | integer | Number of custom domains currently linked to this certificate | |
| 86 | + |
| 87 | +## Errors |
| 88 | + |
| 89 | +All errors use a standard envelope: |
| 90 | + |
| 91 | +```json |
| 92 | +{ |
| 93 | + "error": { |
| 94 | + "message": "certificate not found", |
| 95 | + "code": 404, |
| 96 | + "detail": "optional additional context" |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +| Status | Meaning | |
| 102 | +| --- | --- | |
| 103 | +| 400 | Malformed request – invalid certificate or key, certificate/key mismatch, invalid chain, invalid query parameter, or the certificate has linked domains and cannot be deleted | |
| 104 | +| 401 | Missing or invalid authentication | |
| 105 | +| 404 | Certificate not found, or not owned by your company | |
| 106 | +| 409 | Conflict – a certificate with the same key material already exists | |
| 107 | +| 500 | Internal server error | |
| 108 | + |
| 109 | +## Endpoints |
| 110 | + |
| 111 | +### List Certificates {#list-certificates} |
| 112 | + |
| 113 | +``` |
| 114 | +GET /v1/certificates |
| 115 | +``` |
| 116 | + |
| 117 | +Returns the central certificates owned by your company, most recently updated first. Supports filtering and pagination. |
| 118 | + |
| 119 | +#### Query Parameters |
| 120 | + |
| 121 | +| Parameter | Type | Default | Notes | |
| 122 | +| :---: | :---: | :---: | --- | |
| 123 | +| `domain` | string | – | Filter to certificates linked to this domain | |
| 124 | +| `status` | string | – | Filter by status: `UPCOMING`, `VALID`, `EXPIRES SOON`, `EXPIRED` | |
| 125 | +| `page` | integer | 1 | 1-based page number | |
| 126 | +| `limit` | integer | 10 | Page size, 1–100 | |
| 127 | + |
| 128 | +**Response 200:** |
| 129 | + |
| 130 | +```json |
| 131 | +{ |
| 132 | + "certificates": [ { "...": "certificate object" } ], |
| 133 | + "page": 1, |
| 134 | + "limit": 10, |
| 135 | + "totalCount": 3 |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +### Create a Certificate {#create-certificate} |
| 140 | + |
| 141 | +``` |
| 142 | +POST /v1/certificates |
| 143 | +``` |
| 144 | + |
| 145 | +#### Request Body |
| 146 | + |
| 147 | +```json |
| 148 | +{ |
| 149 | + "certificate": "-----BEGIN CERTIFICATE-----...", |
| 150 | + "privateKey": "-----BEGIN PRIVATE KEY-----...", |
| 151 | + "intermediateChain": "-----BEGIN CERTIFICATE-----...", |
| 152 | + "description": "Wildcard cert for example.com" |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +| Field | Required | Notes | |
| 157 | +| --- | :---: | --- | |
| 158 | +| `certificate` | Yes | PEM-encoded leaf certificate | |
| 159 | +| `privateKey` | Yes | PEM-encoded private key matching the certificate | |
| 160 | +| `intermediateChain` | No | PEM-encoded intermediate chain | |
| 161 | +| `description` | No | Auto-generated from the certificate if omitted | |
| 162 | + |
| 163 | +{{% alert color="info" %}} |
| 164 | +Certificates generated from a Mendix-issued CSR are not supported by this endpoint. |
| 165 | +{{% /alert %}} |
| 166 | + |
| 167 | +**Response:** 201 with the created certificate object. |
| 168 | + |
| 169 | +### Update a Certificate {#update-certificate} |
| 170 | + |
| 171 | +``` |
| 172 | +PATCH /v1/certificates/{certificateId} |
| 173 | +``` |
| 174 | + |
| 175 | +Partially updates a certificate's material or description. Any combination of fields may be supplied. |
| 176 | + |
| 177 | +#### Request Body |
| 178 | + |
| 179 | +```json |
| 180 | +{ |
| 181 | + "certificate": "-----BEGIN CERTIFICATE-----...", |
| 182 | + "intermediateChain": "-----BEGIN CERTIFICATE-----...", |
| 183 | + "description": "Renewed cert" |
| 184 | +} |
| 185 | +``` |
| 186 | + |
| 187 | +**Response:** 200 with the updated certificate object. |
| 188 | + |
| 189 | +### Replace a Certificate {#replace-certificate} |
| 190 | + |
| 191 | +``` |
| 192 | +PUT /v1/certificates/{certificateId}/replacement |
| 193 | +``` |
| 194 | + |
| 195 | +Rotates a certificate – transfers all custom domains linked to `{certificateId}` onto another certificate you own, without downtime for the linked domains. Both certificates must be central certificates owned by your company. |
| 196 | + |
| 197 | +#### Request Body |
| 198 | + |
| 199 | +```json |
| 200 | +{"newCertificateId": "8f14e45f-ceea-467e-8459-b17dc4536f43"} |
| 201 | +``` |
| 202 | + |
| 203 | +**Response:** 200. With the new certificate's object (now carrying the transferred domain links). |
| 204 | + |
| 205 | +### Delete a Certificate {#delete-certificate} |
| 206 | + |
| 207 | +Deletes a central certificate. |
| 208 | + |
| 209 | +``` |
| 210 | +DELETE /v1/certificates/{certificateId} |
| 211 | +``` |
| 212 | + |
| 213 | +{{% alert color="warning" %}} |
| 214 | +A certificate that is still linked to one or more custom domains cannot be deleted. Replace or unlink it first. |
| 215 | +{{% /alert %}} |
| 216 | + |
| 217 | +**Response:** 204 No Content |
0 commit comments