# Certificates TLS certificates InfraNest tracks or issues, and when they expire. **Common tasks** - [List certificates and when they expire](#get-organizations-organization-certificates) - [See which hosts have no certificate](#get-organizations-organization-certificates-coverage) **Only in the app:** Ordering and renewing certificates. **How it works in the app:** [help article](https://infranest.io/docs/ssl-certificates). **Scopes:** Read with `domains.read` or `monitoring.read`, change with `monitoring.write`. See [Tokens and scopes](../tokens-and-scopes.md#scopes).
[Certificates](#certificates) 15
Every endpoint below takes a token in the `Authorization: Bearer` header and answers JSON. Errors use the shared format in [Errors](../errors.md). Base address: `https://api.infranest.io/api`. ## Certificates ### List certificates {#get-organizations-organization-certificates}
`GET` `/organizations/{organization}/certificates` **Scope:** `monitoring.read` · **Changes data:** no Every TLS certificate in the organization, expired and expiring first, each with its health, findings and who renews it. Narrow it with `domain_id` or `monitoring_check_id`; the list is not paginated. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json [ { "id": 10, "organization_id": 1, "source": "manual", "monitoring_check_id": null, "domain_id": null, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "61e58004edb797c08c1261beb441b56e31cc903bde63441cd503dca9aa79f099", "subject": "vpn.northwind.example", "issuer": "vpn.northwind.example", "serial": "EAABC774", "sans": [ "vpn.northwind.example" ], "not_before": "2025-01-03T12:00:00.000000Z", "not_after": "2026-01-03T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "rsa", "key_bits": 4096, "sig_algo": "SHA256-RSA", "trust": "self_signed", "validation": "OV", "is_wildcard": false, "is_multi_san": false, "managed": false, "renewal_source": null, "classification_override": null, "status": "expired", "superseded_by_id": null, "dismissed_at": null, "deployment_locations": [], "owner": null, "notes": null, "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": null, "chain_status": null, "sources": [ { "source": "manual", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": null, "caissuer_url": null, "no_auto_merge": false, "price_yearly": "0.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "internal", "renewal_type_basis": "guess", "served_status": null, "served_checked_at": null, "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null, "custom_fields": [], "renewer": null, "findings": [ { "tier": "problem", "code": "expired", "severity": "critical", "subject": { "type": "certificate", "id": 10, "name": "vpn.northwind.example" }, "certificate_ids": [ 10 ], "addresses": [], "attention_key": "certificate:10", "due_at": "2026-01-03T12:00:00+00:00", "evidence": { "expires_at": "2026-01-03T12:00:00+00:00", "days_left": -12, "renews_itself": false, "renewal_type": "internal", "renewal_type_basis": "guess", "renewal_source": null, "issuer": "vpn.northwind.example", "served_status": null, "role": null, "renewer": null }, "copy": { "title": { "key": "certificates.rules.expired.title", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "detail": { "key": "certificates.rules.expired.detail", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "short": { "key": "certificates.rules.expired.short", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } } }, "fix": { "kind": "route", "label": "certificates.rules.expired.fix", "route": "/certificates/10" }, "dismissible": false, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] } ], "finding": { "tier": "problem", "code": "expired", "severity": "critical", "subject": { "type": "certificate", "id": 10, "name": "vpn.northwind.example" }, "certificate_ids": [ 10 ], "addresses": [], "attention_key": "certificate:10", "due_at": "2026-01-03T12:00:00+00:00", "evidence": { "expires_at": "2026-01-03T12:00:00+00:00", "days_left": -12, "renews_itself": false, "renewal_type": "internal", "renewal_type_basis": "guess", "renewal_source": null, "issuer": "vpn.northwind.example", "served_status": null, "role": null, "renewer": null }, "copy": { "title": { "key": "certificates.rules.expired.title", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "detail": { "key": "certificates.rules.expired.detail", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "short": { "key": "certificates.rules.expired.short", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } } }, "fix": { "kind": "route", "label": "certificates.rules.expired.fix", "route": "/certificates/10" }, "dismissible": false, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] }, "health": { "grade": "warning", "letter": null, "issues": [ { "code": "self_signed", "severity": "warning" } ] }, "in_use": false, "tags": [], "check": null, "domain": null }, { "id": 2, "organization_id": 1, "source": "probe", "monitoring_check_id": 2, "domain_id": 3, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "b6b045177e3469ad718546c6233a2b7f0166d10e466deeaa6d16f6244f6654db", "subject": "northwind-app.dev", "issuer": "Let's Encrypt (R11)", "serial": "B4B32EC4", "sans": [ "northwind-app.dev", "*.northwind-app.dev" ], "not_before": "2025-11-07T12:00:00.000000Z", "not_after": "2026-02-05T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "ecdsa", "key_bits": 256, "sig_algo": "ECDSA-SHA256", "trust": "public", "validation": "DV", "is_wildcard": true, "is_multi_san": true, "managed": true, "renewal_source": "Let's Encrypt (R11)", "classification_override": null, "status": "expiring_soon", "superseded_by_id": null, "dismissed_at": null, "deployment_locations": [ { "endpoint": "northwind-app.dev:443", "last_seen": "2026-01-15T11:50:00+00:00", "first_seen": "2026-01-08T12:00:00+00:00" } ], "owner": null, "notes": null, "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": [ { "subject": "northwind-app.dev", "issuer": "Let's Encrypt (R11)", "is_ca": false, "self_signed": false, "not_after": "2026-02-05T12:00:00+00:00", "fingerprint": "b6b045177e3469ad718546c6233a2b7f0166d10e466deeaa6d16f6244f6654db" }, { "subject": "Let's Encrypt (R11)", "issuer": "ISRG Root X1", "is_ca": true, "self_signed": false, "not_after": "2030-01-15T12:00:00+00:00", "fingerprint": "c12c8a7dcb3f10b2cfd6efb6d14e6516f76cb6d3537ffae6a1f804b618d0cf3c" } ], "chain_status": "trusted", "sources": [ { "source": "probe", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": null, "caissuer_url": "http://r11.i.lencr.org/", "no_auto_merge": false, "price_yearly": "0.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "automatic", "renewal_type_basis": "guess", "served_status": "served", "served_checked_at": "2026-01-15T11:50:00.000000Z", "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null, "custom_fields": [], "renewer": null, "findings": [ { "tier": "problem", "code": "renewal_overdue", "severity": "warning", "subject": { "type": "certificate", "id": 2, "name": "northwind-app.dev" }, "certificate_ids": [ 2 ], "addresses": [ "northwind-app.dev:443" ], "attention_key": "certificate_renewal:2", "due_at": "2026-02-05T12:00:00+00:00", "evidence": { "expires_at": "2026-02-05T12:00:00+00:00", "days_left": 21, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "renews_around_at": "2026-01-06T00:00:00+00:00", "last_seen_at": "2026-01-15T06:00:00+00:00" }, "copy": { "title": { "key": "certificates.rules.renewal_overdue.title", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } }, "detail": { "key": "certificates.rules.renewal_overdue.detail", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } }, "short": { "key": "certificates.rules.renewal_overdue.short", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } } }, "fix": { "kind": "route", "label": "certificates.rules.renewal_overdue.fix", "route": "/certificates/2" }, "dismissible": true, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] } ], "finding": { "tier": "problem", "code": "renewal_overdue", "severity": "warning", "subject": { "type": "certificate", "id": 2, "name": "northwind-app.dev" }, "certificate_ids": [ 2 ], "addresses": [ "northwind-app.dev:443" ], "attention_key": "certificate_renewal:2", "due_at": "2026-02-05T12:00:00+00:00", "evidence": { "expires_at": "2026-02-05T12:00:00+00:00", "days_left": 21, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "renews_around_at": "2026-01-06T00:00:00+00:00", "last_seen_at": "2026-01-15T06:00:00+00:00" }, "copy": { "title": { "key": "certificates.rules.renewal_overdue.title", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } }, "detail": { "key": "certificates.rules.renewal_overdue.detail", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } }, "short": { "key": "certificates.rules.renewal_overdue.short", "params": { "renews_at": "2026-01-06T00:00:00+00:00", "expires_at": "2026-02-05T12:00:00+00:00", "n": 9, "name": "northwind-app.dev" } } }, "fix": { "kind": "route", "label": "certificates.rules.renewal_overdue.fix", "route": "/certificates/2" }, "dismissible": true, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] }, "health": { "grade": "good", "letter": "A", "issues": [] }, "in_use": true, "tags": [ { "id": 6, "name": "Northwind Platform", "color": "#14b8a6", "pivot": { "taggable_type": "App\\Models\\SslCertificate", "taggable_id": 2, "tag_id": 6 } } ], "check": { "id": 2, "name": "App — northwind-app.dev", "target": "https://northwind-app.dev", "interval_minutes": 0 }, "domain": { "id": 3, "name": "northwind-app", "tld": "dev", "full_name": "northwind-app.dev", "archivable": true, "dns_host": null, "management": "tracked", "sync_halt": null } } ] ```
--- ### Get a certificate {#get-organizations-organization-certificates-sslcertificate}
`GET` `/organizations/{organization}/certificates/{sslCertificate}` **Scope:** `monitoring.read` · **Changes data:** no One certificate with its domain, server, monitor, owner and tags, where it is served and its place in the renewal series. Also includes its findings and whether its files can be fetched from the provider. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "id": 1, "organization_id": 1, "source": "probe", "monitoring_check_id": 1, "domain_id": 1, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9", "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "serial": "2395BA42", "sans": [ "northwind.com", "www.northwind.com" ], "not_before": "2025-12-30T12:00:00.000000Z", "not_after": "2026-03-30T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "rsa", "key_bits": 2048, "sig_algo": "SHA256-RSA", "trust": "public", "validation": "DV", "is_wildcard": false, "is_multi_san": true, "managed": true, "renewal_source": "Let's Encrypt (R3)", "classification_override": null, "status": "valid", "superseded_by_id": null, "dismissed_at": null, "deployment_locations": [ { "endpoint": "northwind.com:443", "last_seen": "2026-01-15T11:50:00+00:00", "first_seen": "2026-01-08T12:00:00+00:00" } ], "owner": null, "notes": null, "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": [ { "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "is_ca": false, "self_signed": false, "not_after": "2026-03-30T12:00:00+00:00", "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9" }, { "subject": "Let's Encrypt (R3)", "issuer": "ISRG Root X1", "is_ca": true, "self_signed": false, "not_after": "2030-01-15T12:00:00+00:00", "fingerprint": "e04ca19ed66485fb479283c98fbfb4cda1ab67de1965304902bec3f6a55a2c8e" } ], "chain_status": "trusted", "sources": [ { "source": "probe", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": "ok", "caissuer_url": "http://r3.i.lencr.org/", "no_auto_merge": false, "price_yearly": "0.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "automatic", "renewal_type_basis": "guess", "served_status": "served", "served_checked_at": "2026-01-15T11:50:00.000000Z", "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null, "health": { "grade": "good", "letter": "A", "issues": [] }, "in_use": true, "tags": [ { "id": 5, "name": "Northwind Retail", "color": "#0ea5e9", "pivot": { "taggable_type": "App\\Models\\SslCertificate", "taggable_id": 1, "tag_id": 5 } } ], "check": { "id": 1, "name": "Marketing site", "target": "https://northwind.com", "interval_minutes": 0 }, "domain": { "id": 1, "name": "northwind", "tld": "com", "full_name": "northwind.com", "archivable": true, "dns_host": null, "management": "tracked", "sync_halt": null }, "cloud_server": null, "provider_credential": null, "superseded_by": null, "owner_user": null, "owner_candidates": [ { "id": 1, "name": "Alex Rivera" }, { "id": 3, "name": "Priya Raghunathan" } ], "bundle_available": false, "whereabouts": { "role": "current", "current_certificate": null, "renewer": null, "served_on": [ { "endpoint_id": 1, "host": "northwind.com", "port": 443, "as": "edge", "proxied": true, "last_checked_at": "2026-01-15T11:50:00+00:00", "last_check_source": "scan", "zone": { "id": 1, "name": "northwind.com", "domain_id": 1 }, "dns_record": { "id": 1, "type": "A", "name": "@", "value": "198.51.100.10" }, "cloud_server": { "id": 1, "name": "web-01" }, "monitor": { "id": 1, "name": "Marketing site" }, "renewer": null } ], "lifecycle": { "previous": null, "next": null, "replaced_at": null, "renewals": 0, "lead_days": null, "expected_renewal_at": "2026-02-28T12:00:00+00:00" }, "rollout": null }, "findings": [] } ```
--- ### Update a certificate {#patch-organizations-organization-certificates-sslcertificate}
`PATCH` `/organizations/{organization}/certificates/{sslCertificate}` **Scope:** `monitoring.write` · **Changes data:** yes — only where API writes are switched on for the organization Changes InfraNest’s record of the certificate: owner, notes, subscription end date, seller, tags and any corrections to how it is classified (purpose, trust, validation, managed, renewal type). Only the fields you send change; `owner_user_id` must be a member of the organization. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | | `owner`
body | string, nullable | Must not be greater than 255 characters. | | `owner_user_id`
body | integer, nullable | A member who owns it; checked against the organization below. | | `notes`
body | string, nullable | Must not be greater than 2000 characters. | | `subscription_ends_at`
body | string, nullable | A paid certificate's subscription and who sold it. Must be a valid date. | | `seller`
body | string, nullable | Must not be greater than 255 characters. | | `classification_override`
body | object, nullable | | | `tag_ids`
body | array | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`validation_failed`](../errors.md#validation_failed), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X PATCH "https://api.infranest.io/api/organizations/42/certificates/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"owner":"Platform team","notes":"Renewed automatically by the load balancer."}' ``` **Response** · 200 ```json { "id": 1, "organization_id": 1, "source": "probe", "monitoring_check_id": 1, "domain_id": 1, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9", "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "serial": "2395BA42", "sans": [ "northwind.com", "www.northwind.com" ], "not_before": "2025-12-30T12:00:00.000000Z", "not_after": "2026-03-30T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "rsa", "key_bits": 2048, "sig_algo": "SHA256-RSA", "trust": "public", "validation": "DV", "is_wildcard": false, "is_multi_san": true, "managed": true, "renewal_source": "Let's Encrypt (R3)", "classification_override": null, "status": "valid", "superseded_by_id": null, "dismissed_at": null, "deployment_locations": [ { "endpoint": "northwind.com:443", "last_seen": "2026-01-15T11:50:00+00:00", "first_seen": "2026-01-08T12:00:00+00:00" } ], "owner": "Platform team", "notes": "Renewed automatically by the load balancer.", "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": [ { "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "is_ca": false, "self_signed": false, "not_after": "2026-03-30T12:00:00+00:00", "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9" }, { "subject": "Let's Encrypt (R3)", "issuer": "ISRG Root X1", "is_ca": true, "self_signed": false, "not_after": "2030-01-15T12:00:00+00:00", "fingerprint": "e04ca19ed66485fb479283c98fbfb4cda1ab67de1965304902bec3f6a55a2c8e" } ], "chain_status": "trusted", "sources": [ { "source": "probe", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": "ok", "caissuer_url": "http://r3.i.lencr.org/", "no_auto_merge": false, "price_yearly": "0.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "automatic", "renewal_type_basis": "guess", "served_status": "served", "served_checked_at": "2026-01-15T11:50:00.000000Z", "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null, "tags": [ { "id": 5, "name": "Northwind Retail", "color": "#0ea5e9", "pivot": { "taggable_type": "App\\Models\\SslCertificate", "taggable_id": 1, "tag_id": 5 } } ], "owner_user": null } ```
--- ### Get a certificate’s files from the provider {#get-organizations-organization-certificates-sslcertificate-bundle}
`GET` `/organizations/{organization}/certificates/{sslCertificate}/bundle` **Scope:** `monitoring.read` · **Changes data:** no Asks the provider the certificate came from for its files and returns the files; each fetch is recorded in your audit log. Requires write access, and is refused when the certificate did not come from a connected provider that can hand files back or is not linked to a domain. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/1/bundle" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ```
--- ### Preview the CAA fix for a certificate {#get-organizations-organization-certificates-sslcertificate-caa-fix}
`GET` `/organizations/{organization}/certificates/{sslCertificate}/caa-fix` **Scope:** `monitoring.read` · **Changes data:** no The exact CAA record that would let this certificate’s authority issue it again, the DNS zone it would go in, the CAA records already there and any other certificate it would block. Refused when the certificate’s CAA policy does not block its renewal; nothing is changed. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/1/caa-fix" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ```
--- ### Dismiss or restore a certificate {#post-organizations-organization-certificates-sslcertificate-dismiss}
`POST` `/organizations/{organization}/certificates/{sslCertificate}/dismiss` **Scope:** `monitoring.write` · **Changes data:** yes — only where API writes are switched on for the organization Sets the certificate aside so it no longer counts towards domain coverage. Send `dismissed: false` to restore it. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X POST "https://api.infranest.io/api/organizations/42/certificates/1/dismiss" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "id": 1, "organization_id": 1, "source": "probe", "monitoring_check_id": 1, "domain_id": 1, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9", "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "serial": "2395BA42", "sans": [ "northwind.com", "www.northwind.com" ], "not_before": "2025-12-30T12:00:00.000000Z", "not_after": "2026-03-30T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "rsa", "key_bits": 2048, "sig_algo": "SHA256-RSA", "trust": "public", "validation": "DV", "is_wildcard": false, "is_multi_san": true, "managed": true, "renewal_source": "Let's Encrypt (R3)", "classification_override": null, "status": "valid", "superseded_by_id": null, "dismissed_at": "2026-01-15T12:00:00.000000Z", "deployment_locations": [ { "endpoint": "northwind.com:443", "last_seen": "2026-01-15T11:50:00+00:00", "first_seen": "2026-01-08T12:00:00+00:00" } ], "owner": null, "notes": null, "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": [ { "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "is_ca": false, "self_signed": false, "not_after": "2026-03-30T12:00:00+00:00", "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9" }, { "subject": "Let's Encrypt (R3)", "issuer": "ISRG Root X1", "is_ca": true, "self_signed": false, "not_after": "2030-01-15T12:00:00+00:00", "fingerprint": "e04ca19ed66485fb479283c98fbfb4cda1ab67de1965304902bec3f6a55a2c8e" } ], "chain_status": "trusted", "sources": [ { "source": "probe", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": "ok", "caissuer_url": "http://r3.i.lencr.org/", "no_auto_merge": false, "price_yearly": "0.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "automatic", "renewal_type_basis": "guess", "served_status": "served", "served_checked_at": "2026-01-15T11:50:00.000000Z", "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null, "tags": [ { "id": 5, "name": "Northwind Retail", "color": "#0ea5e9", "pivot": { "taggable_type": "App\\Models\\SslCertificate", "taggable_id": 1, "tag_id": 5 } } ] } ```
--- ### Set a certificate’s price {#put-organizations-organization-certificates-sslcertificate-pricing}
`PUT` `/organizations/{organization}/certificates/{sslCertificate}/pricing` **Scope:** `monitoring.write` · **Changes data:** yes — only where API writes are switched on for the organization Sets the yearly price InfraNest counts for this certificate, with optional currency and billing interval. Send an empty price to go back to the provider’s figure. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`validation_failed`](../errors.md#validation_failed), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X PUT "https://api.infranest.io/api/organizations/42/certificates/1/pricing" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"price_yearly":59,"currency":"EUR"}' ``` **Response** · 200 ```json { "id": 1, "organization_id": 1, "source": "probe", "monitoring_check_id": 1, "domain_id": 1, "cloud_server_id": null, "provider_credential_id": null, "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9", "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "serial": "2395BA42", "sans": [ "northwind.com", "www.northwind.com" ], "not_before": "2025-12-30T12:00:00.000000Z", "not_after": "2026-03-30T12:00:00.000000Z", "purpose": "tls_server", "key_algo": "rsa", "key_bits": 2048, "sig_algo": "SHA256-RSA", "trust": "public", "validation": "DV", "is_wildcard": false, "is_multi_san": true, "managed": true, "renewal_source": "Let's Encrypt (R3)", "classification_override": null, "status": "valid", "superseded_by_id": null, "dismissed_at": null, "deployment_locations": [ { "endpoint": "northwind.com:443", "last_seen": "2026-01-15T11:50:00+00:00", "first_seen": "2026-01-08T12:00:00+00:00" } ], "owner": null, "notes": null, "first_seen_at": "2025-11-16T12:00:00.000000Z", "last_seen_at": "2026-01-15T06:00:00.000000Z", "created_at": "2026-01-15T12:00:00.000000Z", "updated_at": "2026-01-15T12:00:00.000000Z", "subject_org": null, "subject_location": null, "chain": [ { "subject": "northwind.com", "issuer": "Let's Encrypt (R3)", "is_ca": false, "self_signed": false, "not_after": "2026-03-30T12:00:00+00:00", "fingerprint": "6f6f72db300125c26f8b2c866124ffb57e60a201177144ed5e5b6711eba24cb9" }, { "subject": "Let's Encrypt (R3)", "issuer": "ISRG Root X1", "is_ca": true, "self_signed": false, "not_after": "2030-01-15T12:00:00+00:00", "fingerprint": "e04ca19ed66485fb479283c98fbfb4cda1ab67de1965304902bec3f6a55a2c8e" } ], "chain_status": "trusted", "sources": [ { "source": "probe", "last_seen": "2026-01-15T06:00:00+00:00", "first_seen": "2025-11-16T12:00:00+00:00" } ], "crl_url": null, "ocsp_url": null, "caa_status": "ok", "caissuer_url": "http://r3.i.lencr.org/", "no_auto_merge": false, "price_yearly": "59.00", "price_source": "manual", "price_currency": "EUR", "billing_interval": "yearly", "interval_count": 1, "renewal_type": "automatic", "renewal_type_basis": "guess", "served_status": "served", "served_checked_at": "2026-01-15T11:50:00.000000Z", "subscription_ends_at": null, "seller": null, "role": null, "ct_finding": null, "owner_user_id": null } ```
--- ### Get a certificate’s timeline {#get-organizations-organization-certificates-sslcertificate-timeline}
`GET` `/organizations/{organization}/certificates/{sslCertificate}/timeline` **Scope:** `monitoring.read` · **Changes data:** no The certificate’s history across its renewals: when it was issued, renewed and expired, plus the changes recorded in your audit log. For certificates you renew and pay for yourself, it also marks the day to order the renewal and when the subscription ends. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `sslCertificate_id`
path · required | integer | The sslCertificate's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/1/timeline" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "events": [ { "type": "issued", "at": "2025-12-30T12:00:00+00:00", "fingerprint": "6f6f72db3001" } ], "generations": 1, "markers": [] } ```
--- ### Get certificate coverage per domain {#get-organizations-organization-certificates-coverage}
`GET` `/organizations/{organization}/certificates/coverage` **Scope:** `monitoring.read` · **Changes data:** no For each of your domains, whether a certificate covers it (`covered`, `expiring`, `expired` or `uncovered`) and the best certificate that does. Superseded and dismissed certificates are left out. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/coverage" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json [ { "domain_id": 11, "domain": "northwind.cloud", "status": "covered", "certificate": { "id": 6, "subject": "*.northwind.cloud", "not_after": "2026-03-17T12:00:00.000000Z", "status": "valid", "source": "hetzner" } }, { "domain_id": 1, "domain": "northwind.com", "status": "covered", "certificate": { "id": 8, "subject": "cdn.northwind.com", "not_after": "2026-11-11T12:00:00.000000Z", "status": "valid", "source": "cloudflare" } } ] ```
--- ### List certificate findings {#get-organizations-organization-certificates-findings}
`GET` `/organizations/{organization}/certificates/findings` **Scope:** `monitoring.read` · **Changes data:** no Everything InfraNest found about your certificates that may need attention, from problems to recommendations, with counts per tier. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/findings" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "findings": [ { "tier": "problem", "code": "expired", "severity": "critical", "subject": { "type": "certificate", "id": 10, "name": "vpn.northwind.example" }, "certificate_ids": [ 10 ], "addresses": [], "attention_key": "certificate:10", "due_at": "2026-01-03T12:00:00+00:00", "evidence": { "expires_at": "2026-01-03T12:00:00+00:00", "days_left": -12, "renews_itself": false, "renewal_type": "internal", "renewal_type_basis": "guess", "renewal_source": null, "issuer": "vpn.northwind.example", "served_status": null, "role": null, "renewer": null }, "copy": { "title": { "key": "certificates.rules.expired.title", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "detail": { "key": "certificates.rules.expired.detail", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } }, "short": { "key": "certificates.rules.expired.short", "params": { "expires_at": "2026-01-03T12:00:00+00:00", "name": "vpn.northwind.example" } } }, "fix": { "kind": "route", "label": "certificates.rules.expired.fix", "route": "/certificates/10" }, "dismissible": false, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] }, { "tier": "problem", "code": "domain_expires_first", "severity": "warning", "subject": { "type": "certificate", "id": 12, "name": "northwind.shop" }, "certificate_ids": [ 12 ], "addresses": [ "northwind.shop:443" ], "attention_key": "domain:10", "due_at": "2026-01-26T00:00:00+00:00", "evidence": { "expires_at": "2026-03-17T12:00:00+00:00", "days_left": 61, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "domain_id": 10, "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "domain_auto_renew": false }, "copy": { "title": { "key": "certificates.rules.domain_expires_first.title", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } }, "detail": { "key": "certificates.rules.domain_expires_first.detail", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } }, "short": { "key": "certificates.rules.domain_expires_first.short", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } } }, "fix": { "kind": "route", "label": "certificates.rules.domain_expires_first.fix", "route": "/domains/10" }, "dismissible": true, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] } ], "counts": { "problem": 6, "recommendation": 6, "info": 0 } } ```
--- ### Preview domains to add from certificates {#get-organizations-organization-certificates-fixes-domains}
`GET` `/organizations/{organization}/certificates/fixes/domains` **Scope:** `domains.read` · **Changes data:** no The domain names your certificates use that InfraNest does not track yet, where each is registered as far as is known, and the certificates that use it. Also says how many more domains your plan allows; nothing is changed. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/fixes/domains" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "domains": [], "room": null, "allowed": true } ```
--- ### List certificate fixes already applied {#get-organizations-organization-certificates-fixes-done}
`GET` `/organizations/{organization}/certificates/fixes/done` **Scope:** `monitoring.read` · **Changes data:** no The certificate recommendations already acted on, newest first: monitors and domains added from a recommendation and CAA records added to unblock a renewal, with who did it and when. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/fixes/done" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "lines": [] } ```
--- ### Preview monitors to add for certificates {#get-organizations-organization-certificates-fixes-monitors}
`GET` `/organizations/{organization}/certificates/fixes/monitors` **Scope:** `monitoring.read` · **Changes data:** no The addresses InfraNest suggests watching with an SSL monitor, the monitor each would get and the certificates involved. Also says how many more monitors your plan allows; nothing is changed. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/fixes/monitors" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "addresses": [ { "address": "archive.northwind.com:443", "host": "archive.northwind.com", "port": 443, "certificates": [ { "id": 18, "name": "archive.northwind.com" } ], "monitor": { "name": "archive.northwind.com", "type": "ssl", "target": "archive.northwind.com", "interval_seconds": 3600 }, "unsupported": null }, { "address": "billing.northwind.nl:443", "host": "billing.northwind.nl", "port": 443, "certificates": [ { "id": 14, "name": "billing.northwind.nl" } ], "monitor": { "name": "billing.northwind.nl", "type": "ssl", "target": "billing.northwind.nl", "interval_seconds": 3600 }, "unsupported": null } ], "room": null, "allowed": true } ```
--- ### Get the certificate overview {#get-organizations-organization-certificates-overview}
`GET` `/organizations/{organization}/certificates/overview` **Scope:** `monitoring.read` · **Changes data:** no An address-by-address view of the certificates your visitors actually receive, grouped by domain, with a summary, what needs you, the renewals due in the next 90 days and recommendations. Also lists the members who can be made a certificate’s owner. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/certificates/overview" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "summary": { "state": "needs_you", "addresses_needing_you": 5, "other_problems": 1, "first_problem": { "endpoint_id": 7 }, "todo": [ { "endpoint_id": 7, "host": "northwind.shop", "port": 443, "address": "northwind.shop:443", "finding": { "tier": "problem", "code": "domain_expires_first", "severity": "warning", "subject": { "type": "certificate", "id": 12, "name": "northwind.shop" }, "certificate_ids": [ 12 ], "addresses": [ "northwind.shop:443" ], "attention_key": "domain:10", "due_at": "2026-01-26T00:00:00+00:00", "evidence": { "expires_at": "2026-03-17T12:00:00+00:00", "days_left": 61, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "domain_id": 10, "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "domain_auto_renew": false }, "copy": { "title": { "key": "certificates.rules.domain_expires_first.title", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } }, "detail": { "key": "certificates.rules.domain_expires_first.detail", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } }, "short": { "key": "certificates.rules.domain_expires_first.short", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } } }, "fix": { "kind": "route", "label": "certificates.rules.domain_expires_first.fix", "route": "/domains/10" }, "dismissible": true, "advisor": null, "decision": null, "automation": null, "sources": [], "also": [] }, "attention_keys": [ "domain:10" ] } ], "decided": [], "addresses": 12, "domains": 5, "renew_automatically": 8, "monitored": 5, "recommendations": 6, "watched": 1, "next_renewal": { "host": "staging.northwind-app.dev", "more": 0, "at": "2026-01-18T00:00:00+00:00", "who": "automatic" } }, "timeline": [ { "certificate_id": 16, "subject": "northwind-mail.com", "issuer": "Sectigo RSA Organization Validation Secure Server CA", "expires_at": "2026-02-02T12:00:00+00:00", "renews_at": null, "who": "you", "endpoint_ids": [ 11 ], "hosts": [ "mx1.northwind-mail.com" ], "listed": true } ], "needs_you": [ { "kind": "problem", "at": "2026-01-26T00:00:00+00:00", "now": false, "severity": "warning", "endpoint_id": 7, "hosts": [ "northwind.shop" ], "reason": { "key": "certificates.rules.domain_expires_first.short", "params": { "domain": "northwind.shop", "domain_expires_at": "2026-01-26T00:00:00+00:00", "expires_at": "2026-03-17T12:00:00+00:00", "name": "northwind.shop" } }, "who": null } ], "groups": [ { "key": "domain:northwind-mail.com", "domain_id": 16, "name": "northwind-mail.com", "in_domains": true, "rows": [ { "domain_id": 16, "endpoint_id": 11, "host": "mx1.northwind-mail.com", "port": 993, "address": "mx1.northwind-mail.com:993", "status": "problem", "severity": "warning", "reason": { "key": "certificates.rules.rollout_incomplete.short", "params": { "address": "mx1.northwind-mail.com:993", "name": "northwind-mail.com", "done": 1, "total": 2, "expires_at": "2026-02-02T12:00:00+00:00", "server": "mail-01" } }, "check_note": null, "certificate": { "id": 16, "subject": "northwind-mail.com", "issuer": "Sectigo RSA Organization Validation Secure Server CA", "not_after": "2026-02-02T12:00:00+00:00", "status": "superseded", "role": null }, "origin_certificate": null, "served_by": { "kind": "server", "provider": "transip", "provider_label": "TransIP", "cloud_server": { "id": 14, "name": "mail-01" }, "resolved_ips": [ "198.51.100.166" ], "edge_network": null, "network": null, "display": { "kind": "server", "name": "mail-01", "ip": "198.51.100.166" }, "dns_record": { "id": 53, "type": "A", "name": "mx1", "value": "198.51.100.166", "zone": { "id": 9, "name": "northwind-mail.com" } } }, "renewal": { "type": "manual_paid", "source": null, "renews_itself": false, "actor": "you" }, "ownership": { "is": "yours", "basis": "domain", "override": null }, "monitor": null, "last_checked_at": "2026-01-15T11:50:00+00:00", "last_check_source": "scan", "last_attempt_at": "2026-01-15T11:50:00+00:00", "failing": null, "findings": [ { "tier": "problem", "code": "rollout_incomplete", "severity": "warning", "subject": { "type": "address", "id": 11, "name": "mx1.northwind-mail.com:993" }, "certificate_ids": [ 16 ], "addresses": [ "mx1.northwind-mail.com:993" ], "attention_key": "certificate_rollout:11", "due_at": "2026-02-02T12:00:00+00:00", "evidence": { "endpoint_id": 11, "serves_certificate_id": 16, "successor_id": 15, "expires_at": "2026-02-02T12:00:00+00:00", "done": 1, "total": 2, "last_checked_at": "2026-01-15T11:50:00+00:00" }, "copy": { "title": { "key": "certificates.rules.rollout_incomplete.title", "params": { "address": "mx1.northwind-mail.com:993", "name": "northwind-mail.com", "done": 1, "total": 2, "expires_at": "2026-02-02T12:00:00+00:00" } }, "detail": { "key": "certificates.rules.rollout_incomplete.detailServer", "params": { "address": "mx1.northwind-mail.com:993", "name": "northwind-mail.com", "done": 1, "total": 2, "expires_at": "2026-02-02T12:00:00+00:00", "server": "mail-01" }, "count": 2 }, "short": { "key": "certificates.rules.rollout_incomplete.short", "params": { "address": "mx1.northwind-mail.com:993", "name": "northwind-mail.com", "done": 1, "total": 2, "expires_at": "2026-02-02T12:00:00+00:00", "server": "mail-01" } } }, "fix": { "kind": "action", "label": "certificates.rules.rollout_incomplete.fix", "action": "certificate.scan", "method": "POST", "endpoint": "/organizations/1/certificates/scan", "body": { "host": "mx1.northwind-mail.com", "port": 993 } }, "dismissible": true, "advisor": null, "decision": null, "automation": { "template": "cert_rollout_not_live_alert", "action": "send_notification", "provider": null, "connected": true, "conditions": [], "title": { "key": "certificates.automate.cert_rollout_not_live_alert", "params": { "days": 0 } } }, "sources": [ { "source": "check", "tone": "bad", "copy": { "key": "certificates.evidence.check.oldCertificate", "params": [] } } ], "also": [] } ], "set_aside": false } ], "count": 2, "problems": 1, "next_expiry": "2026-02-02T12:00:00+00:00" } ], "watched": [ { "endpoint_id": 13, "host": "status.supplier.example", "port": 443, "address": "status.supplier.example:443", "domain_id": null, "status": "ok", "severity": null, "reason": null, "check_note": null, "certificate": { "id": 19, "subject": "status.supplier.example", "issuer": "Let's Encrypt (R3)", "not_after": "2026-03-28T12:00:00+00:00", "status": "valid", "role": null }, "origin_certificate": null, "served_by": { "kind": "address", "provider": null, "provider_label": null, "cloud_server": null, "resolved_ips": [ "203.0.113.210" ], "edge_network": null, "network": null, "display": { "kind": "ip", "name": "203.0.113.210", "ip": "203.0.113.210" }, "dns_record": null }, "renewal": { "type": "automatic", "source": "Let's Encrypt (R3)", "renews_itself": true, "actor": "automatic" }, "ownership": { "is": "watched", "basis": "none", "override": null }, "monitor": { "id": 13, "name": "Supplier status", "status": "up", "last_checked_at": "2026-01-15T11:58:00+00:00" }, "last_checked_at": "2026-01-15T11:50:00+00:00", "last_check_source": "scan", "last_attempt_at": "2026-01-15T11:50:00+00:00", "failing": null, "findings": [] } ], "recommendations": [ { "tier": "recommendation", "code": "chain_incomplete", "severity": "warning", "subject": { "type": "certificate", "id": 4, "name": "docs.northwind.com" }, "certificate_ids": [ 4 ], "addresses": [ "docs.northwind.com:443" ], "attention_key": null, "due_at": null, "evidence": { "expires_at": "2026-03-08T12:00:00+00:00", "days_left": 52, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "chain_status": "incomplete" }, "copy": { "title": { "key": "certificates.rules.chain_incomplete.title", "params": { "name": "docs.northwind.com" } }, "detail": { "key": "certificates.rules.chain_incomplete.detail", "params": { "name": "docs.northwind.com" } }, "short": { "key": "certificates.rules.chain_incomplete.short", "params": { "name": "docs.northwind.com" } } }, "fix": { "kind": "route", "label": "certificates.rules.chain_incomplete.fix", "route": "/certificates/4" }, "dismissible": true, "advisor": { "resource_type": "certificate", "resource_id": "4", "check_id": "chain" }, "decision": null, "automation": null, "sources": [], "also": [] } ], "recommendation_groups": [ { "code": "chain_incomplete", "severity": "warning", "items": [ { "tier": "recommendation", "code": "chain_incomplete", "severity": "warning", "subject": { "type": "certificate", "id": 4, "name": "docs.northwind.com" }, "certificate_ids": [ 4 ], "addresses": [ "docs.northwind.com:443" ], "attention_key": null, "due_at": null, "evidence": { "expires_at": "2026-03-08T12:00:00+00:00", "days_left": 52, "renews_itself": true, "renewal_type": "automatic", "renewal_type_basis": "guess", "renewal_source": "Let's Encrypt (R11)", "issuer": "Let's Encrypt (R11)", "served_status": "served", "role": null, "renewer": null, "chain_status": "incomplete" }, "copy": { "title": { "key": "certificates.rules.chain_incomplete.title", "params": { "name": "docs.northwind.com" } }, "detail": { "key": "certificates.rules.chain_incomplete.detail", "params": { "name": "docs.northwind.com" } }, "short": { "key": "certificates.rules.chain_incomplete.short", "params": { "name": "docs.northwind.com" } } }, "fix": { "kind": "route", "label": "certificates.rules.chain_incomplete.fix", "route": "/certificates/4" }, "dismissible": true, "advisor": { "resource_type": "certificate", "resource_id": "4", "check_id": "chain" }, "decision": null, "automation": null, "sources": [], "also": [] } ], "count": 1, "copy": { "title": { "key": "certificates.overview.recGroups.chain_incomplete.title", "params": { "n": 1 } }, "detail": { "key": "certificates.overview.recGroups.chain_incomplete.detail", "params": { "n": 1 } } }, "fix": { "kind": "route", "label": "certificates.rules.chain_incomplete.fix", "route": "/certificates/4" }, "dismiss": [ { "resource_type": "certificate", "resource_id": "4", "check_id": "chain" } ] } ], "dismissed_recommendations": [], "tidied": { "replaced": 2, "not_served": 0, "provider": 0, "merged": 1, "dismissed": 0, "untracked": 0 }, "untracked": [], "inventory": [ { "id": 10, "subject": "vpn.northwind.example", "issuer": "vpn.northwind.example", "source": "manual", "sources": [ "manual" ], "not_after": "2026-01-03T12:00:00+00:00", "status": "expired", "role": "not_seen", "hosts": [], "superseded_by_id": null } ], "owner_candidates": [ { "id": 1, "name": "Alex Rivera" } ] } ```
--- ### Assign an owner to certificates {#post-organizations-organization-certificates-owner}
`POST` `/organizations/{organization}/certificates/owner` **Scope:** `monitoring.write` · **Changes data:** yes — only where API writes are switched on for the organization Makes the member given in `user_id` the owner of each certificate in `certificate_ids` (up to 200). Refused when that person is not a member of the organization. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `certificate_ids`
body | array | | | `user_id`
body · required | integer | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X POST "https://api.infranest.io/api/organizations/42/certificates/owner" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"certificate_ids":[1],"user_id":1}' ``` **Response** · 200 ```json { "assigned": 1, "owner": { "id": 1, "name": "Alex Rivera" } } ```