---
title: "Generate a signing certificate"
method: POST
path: "/appsec/7.0/apple/certificates"
tags: ["Certificates"]
---

# Generate a signing certificate

`POST /appsec/7.0/apple/certificates`

Generates an RSA keypair + CSR locally, has Apple sign it, and persists the private key + certificate + expiry. Returns the certificate metadata; download the `.p12` separately.

## Request body

- CreateCertRequest
  - `certificateType` 'IOS_DEVELOPMENT' | 'IOS_DISTRIBUTION' | 'DEVELOPMENT' | 'DISTRIBUTION' | 'MAC_APP_DEVELOPMENT' | 'MAC_APP_DISTRIBUTION' | 'MAC_INSTALLER_DISTRIBUTION' | 'DEVELOPER_ID_APPLICATION' | 'DEVELOPER_ID_INSTALLER', required
  - `displayName` string, nullable — Optional friendly name; also used as the .p12 alias and CSR common name.

## Response `201`

Certificate created

- CertDTO
  - `id` integer
  - `appleCertId` string, nullable — Apple's /v1/certificates resource id.
  - `certificateType` string
  - `displayName` string, nullable
  - `serialNumber` string, nullable
  - `expiresAt` integer, nullable — Expiry in epoch millis (from the X.509 notAfter).
  - `status` 'ACTIVE' | 'REVOKED' | 'EXPIRED'
  - `privateKeyPresent` boolean — True if we hold the private key (a .p12 can be downloaded); false for imported/reconciled certs.

## Other responses

- `400` — Missing or invalid parameters (plain-text reason in the body).
- `403` — Caller is anonymous / not authenticated.
- `409` — The account's App Store Connect API key is missing, was rejected by Apple (revoked, or the Key ID / Issuer ID do not match the .p8), or lacks the access this call needs. The developer has to fix the stored key -- retrying will not clear it. The body is a plain-text explanation written for them.
- `422` — The stored key is fine but Apple refused this particular request (for example "You already have a current Distribution certificate"). The body is a plain-text explanation, carrying Apple's own wording where Apple supplied it.
- `429` — Apple is rate-limiting App Store Connect requests for this team. Retrying after a pause is correct.
- `502` — App Store Connect is down or unreachable, so the call could not be completed. This is the only genuinely upstream failure and the only one worth retrying automatically; anything the developer must act on comes back as 409 or 422 instead.

## Changes

- **2026-08-19** `f0b48d0af96f` — 2 info
  - added the non-success response with the status `422`
  - added the non-success response with the status `429`

[Change history](https://skmtc.dev/codenameone/apis/codename-one-apple-signing-service/changes/appsec/7.0/apple/certificates/post.md)

---

[API](https://skmtc.dev/codenameone/apis/codename-one-apple-signing-service.md) · [All operations](https://skmtc.dev/codenameone/apis/codename-one-apple-signing-service/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/codenameone/codename-one-apple-signing-service/revisions/f0b48d0af96f/schema)
