# Issue an SSL/TLS certificate

> Prove you control a domain by DNS or HTTP and issue a free certificate for it on a website's SSL tab.

Source: https://docs.coritan.com/websites/ssl/issue-a-certificate/

In the dashboard:

- /dashboard/websites/…/ssl: https://www.coritan.com/dashboard/websites

Issue a certificate for a website on its **SSL** tab. You choose how to prove that you control the name, and Coritan installs the certificate on the name's web proxy once the certificate authority issues it. A new web proxy requests its own certificate, so you need these steps for a name that has none, or one whose certificate failed or expired. [How SSL/TLS certificates work](/websites/ssl/) explains the validation methods.

## Before you begin

- The domain must be on your [Websites](https://www.coritan.com/dashboard/websites) list: a zone that Coritan hosts, or a domain registered with Coritan.
- If the domain publishes `CAA` records, they must allow Let's Encrypt, ZeroSSL and Google Trust Services ([DNS record types](/websites/dns/record-types/#rules-for-some-types)).
- The **SSL** tab shows the **Request a certificate** card when the name has no certificate, or when its certificate is `failed` or `expired`.
- The **SSL** tab covers the website's own name, such as `example.com`. For another name with a web proxy, such as `www.example.com`, [request the certificate from the web proxy](#request-a-certificate-for-a-web-proxy).

## Issue a certificate with Coritan DNS

Use this method when Coritan hosts the zone and the domain uses Coritan's nameservers. The dashboard selects it for you in that case.

1. In the dashboard, go to [Websites](https://www.coritan.com/dashboard/websites), open the domain and select the **SSL** tab.
2. On the **Request a certificate** card, select **Coritan DNS (automatic)**.
3. In **Install on proxy route**, keep the website's web proxy, or choose **Zone only** to keep the certificate without installing it.
4. Select **Start validation**. The card shows **Nothing to do**.
5. Select **Issue certificate**.

## Issue a certificate with a TXT record at another DNS provider

Use this method when the domain's DNS is at another provider and the name does not resolve to the Coritan edge. You create the record first with any value, then replace the value once Coritan has ordered the certificate.

1. In the dashboard, go to [Websites](https://www.coritan.com/dashboard/websites), open the domain and select the **SSL** tab.
2. On the **Request a certificate** card, select **Manual DNS TXT record**, then **Start validation**. The card lists a `TXT` record named `_acme-challenge.example.com` with a TTL of `60`, and its value is still empty.
3. At your DNS provider, create a `TXT` record at `_acme-challenge.example.com` with any value, such as `pending`.
4. Wait until the badge reads **TXT record found, value differs**, or select **Check now**.
5. Select **Complete validation**. The card shows **Issuing the certificate**.
6. After a few seconds, reload the page. The card shows the `TXT` record again, now with its value.
7. At your DNS provider, replace the record's value with the one shown. Do it within five minutes of step 5, because Coritan checks for the value for five minutes.

When public resolvers return the new value, the badge reads **TXT record found** and the certificate authority issues the certificate. You do not need to select **Complete validation** again. Delete the `TXT` record once the certificate is `active`.

## Issue a certificate with HTTP validation

Use this method when the name resolves to the Coritan edge, or when you can point it there.

1. In the dashboard, go to [Websites](https://www.coritan.com/dashboard/websites), open the domain and select the **SSL** tab.
2. On the **Request a certificate** card, select **HTTP validation**, then **Start validation**. The card lists an `A` record for the name with the edge address as its value, and the addresses the name resolves to now.
3. If the badge reads **Not pointed at the edge**, set the name's `A` record to the address shown at the DNS provider that answers for the domain.
4. Wait until the badge reads **Ready**. The card checks every few seconds, and **Check now** checks at once.
5. Select **Complete validation**. It stays unavailable until the name resolves to the edge address.

Keep the name pointed at the edge after the certificate is issued. Renewal validates the same way.

## Request a certificate for a web proxy

A web proxy's **Overview** tab has its own **Certificate** card. Use it for a name that has no **SSL** tab, such as `www.example.com`.

1. In the dashboard, go to [Edge Proxy](https://www.coritan.com/dashboard/proxies) and open the web proxy.
2. On the **Overview** tab, find the **Certificate** card and select **Request certificate**. The button appears when the proxy has no `active` certificate and none is being issued.

The card shows **Issuance in progress** while the certificate authority validates the name. Coritan uses a certificate that already covers the name when there is one. Otherwise it validates over HTTP, so the name must resolve to the edge, and it falls back to Coritan DNS when Coritan hosts the zone.

## Result

The dashboard confirms `Certificate issuance for example.com started.` The **Certificate** card shows `pending` while the certificate authority validates the name, then `active` with the **Issuer** and **Expires** rows. The web proxy for the name serves the certificate. With **Zone only**, the certificate waits on your account until a web proxy for the name requests one.

## Troubleshooting

`This domain has reached its weekly issuance limit.`
: The registered domain is at its issuance limit, and **Start validation** is unavailable. Wait until the count on the **Issuance limit** card falls.

`Rate limit: 45/45 certificates issued by all authorities for example.com in the past 7 days`
: The same limit, reported when you start validation. Wait until older certificates leave the seven-day window.

`You must own this domain via registration, DNS zone, or proxy route`
: The name is not on your account. Add its zone first ([Add a domain you already own](/websites/add-an-existing-domain/)).

`No TXT record found at _acme-challenge.example.com. Please add the record and try again.`
: Public resolvers do not return a `TXT` record at that name yet. Check the record's name at your DNS provider, wait for it to appear, and select **Complete validation** again.

`Domain does not resolve to this server (203.0.113.10). Current IPs: none. Update your A record and try again.`
: The name does not resolve to the edge address. Set its `A` record to the address in the message and try again once the change has spread.

`Certificate issuance already in progress`
: Coritan is already issuing a certificate for the name. Wait for the **Certificate** card to show the result.

**The last request failed** mentions `DNS verification failed`
: Coritan did not see the `TXT` value within five minutes. Start again with **Manual DNS TXT record**, and replace the value as soon as it appears.

**The last request failed** mentions `HTTP verification failed`
: Coritan could not fetch the validation file from the name over HTTP. Check that the name resolves only to the edge address and that port 80 reaches the edge. Then start again.

**The last request failed** mentions `CAA`
: A `CAA` record for the domain does not allow the certificate authorities that Coritan uses. Add an `issue` record for each one, then start again.

## Related

- [How SSL/TLS certificates work](/websites/ssl/)
- [Renew or revoke a certificate](/websites/ssl/renew-or-revoke-a-certificate/)
- [Create a web proxy](/proxies/web-proxies/create-a-web-proxy/)

## With the API

The **SSL** tab runs a challenge in three calls: start it, read its status, then complete it. Start a challenge with a `method` of `auto` (the default), `dns_automatic`, `dns_manual` or `http`:

```bash
curl -X POST https://api.coritan.com/api/v1/ssl/challenges/start \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "method": "http"}'
```

The answer is `201` with what to do next. `auto` answers with the method it picked:

```json
{
  "domain": "example.com",
  "method": "http",
  "status": "not_pointed",
  "txt_name": null,
  "txt_value": null,
  "expected_ip": "203.0.113.10",
  "current_ips": ["198.51.100.7"],
  "is_pointed": false,
  "instructions": "Point your domain's A record to 203.0.113.10, then call the /complete endpoint. Current resolution: 198.51.100.7",
  "created_at": "2026-09-25T10:00:00Z",
  "expires_at": "2026-09-25T11:00:00Z"
}
```

`status` is `ready` or `not_pointed` for `http`, and `ready` for `dns_automatic`. For `dns_manual` it starts as `awaiting_order`, with `txt_name` set and `txt_value` still `null`. Read it again with the status call. For a manual challenge the status is `awaiting_record` while there is no record, `txt_found` while the record holds another value, and `verified` once it holds `txt_value`. Without a manual challenge in progress, the call reports whether the name points at the edge:

```bash
curl https://api.coritan.com/api/v1/ssl/challenges/example.com/status \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

Complete an `http` or `dns_manual` challenge to order the certificate. The answer is `202`:

```bash
curl -X POST https://api.coritan.com/api/v1/ssl/challenges/example.com/complete \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{
  "message": "Certificate issuance started via HTTP verification",
  "job_id": 5812,
  "domain": "example.com"
}
```

For `dns_manual` the message is `Certificate issuance started via manual DNS verification`. Read the status again after a few seconds: `txt_value` now holds the value to publish.

A `dns_automatic` challenge has nothing to complete. Order the certificate directly instead, which is what **Issue certificate** does. `challenge_method` is `dns01` or `http01`, and leaving it out lets Coritan choose. `route_id` installs the certificate on the web proxy with that ID, for the same name:

```bash
curl -X POST https://api.coritan.com/api/v1/ssl/certificates \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "challenge_method": "dns01", "route_id": 31}'
```

```json
{
  "message": "Certificate issuance queued",
  "job_id": 5813,
  "domain": "example.com"
}
```

The call answers `403` with `You must own the domain's DNS zone or domain registration` for a name outside your zones and registered domains, and `404` with `Route not found or access denied` for a `route_id` that is not yours. Poll [the certificate status](/websites/ssl/#read-certificates-with-the-api) until `certificate.status` is no longer `pending`.

## API

- `POST /api/v1/ssl/certificates`: Request SSL certificate issuance for a domain owned by the user (https://docs.coritan.com/api/reference/client/ssl/#op-post-api-v1-ssl-certificates)
- `POST /api/v1/ssl/challenges/start`: Start an SSL challenge for a domain (https://docs.coritan.com/api/reference/client/ssl/#op-post-api-v1-ssl-challenges-start)
- `POST /api/v1/ssl/challenges/{domain}/complete`: Finalize verification and trigger certificate issuance (https://docs.coritan.com/api/reference/client/ssl/#op-post-api-v1-ssl-challenges-domain-complete)
- `GET /api/v1/ssl/challenges/{domain}/status`: Check the current verification status for a domain (https://docs.coritan.com/api/reference/client/ssl/#op-get-api-v1-ssl-challenges-domain-status)
