# Apps

Your app: the origin every customer domain forwards to, white-label, webhooks and the signing secret.

Base URL `https://api.apexly.dev`. Send your key as `Authorization: Bearer sk_live_…` or `sk_test_…`; the examples read it from `APEXLY_API_KEY`.

## Get the API key's app

`GET /v1/apps/current`

### Response

`200 OK`. Errors use the [error envelope](/docs/api/errors).

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | app_… |
| `name` | `string` |  |
| `origin_url` | `string \| null` | Where every customer domain forwards, e.g. https://app.hireflow.com. |
| `origin_reachable` | `boolean` | Result of the latest probe. |
| `origin_latency_ms` | `integer \| null` | Latency of the latest successful probe. |
| `origin_checked_at` | `string \| null` | When the origin was last probed (RFC 3339). |
| `origin_status_reason` | `string \| null` | Why the latest probe failed: origin_not_allowed \| origin_dns_failed \| origin_timeout \| origin_tls_error \| origin_connection_failed \| origin_http_error \| origin_too_many_redirects \| origin_bad_redirect. |
| `origin_unreachable` | `boolean` | True after 3 consecutive failed probes (re-probed every 15 minutes). |
| `webhook_url` | `string \| null` |  |
| `whitelabel_host` | `string \| null` |  |
| `whitelabel_verified` | `boolean` |  |
| `whitelabel_target` | `string` | What whitelabel_host must CNAME to, e.g. edge.apexly.dev. |
| `whitelabel_status_reason` | `string \| null` | whitelabel_unverified while whitelabel_host is set but its CNAME chain does not reach whitelabel_target. One of `whitelabel_unverified`. |
| `whitelabel_found` | `string \| null` | The CNAME last seen at whitelabel_host while unverified (null = no record). |
| `whitelabel_checked_at` | `string \| null` | When whitelabel_host was last checked (every 6 hours once verified). |
| `whitelabel_grace_ends_at` | `string \| null` | Set when a verified host broke: domains routed through it keep serving until then, then go dns_broken. |
| `apex_redirect_default` | `string` | One of `none`, `www`. |
| `created_at` | `string` |  |

### Example

```bash tab="curl"
curl https://api.apexly.dev/v1/apps/current \
  -H "Authorization: Bearer $APEXLY_API_KEY"
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/apps/current", {
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
  },
});
const body = await res.json();
```

```python tab="Python"
import os
import requests

res = requests.get(
    "https://api.apexly.dev/v1/apps/current",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
)
body = res.json()
```

## Update the API key's app

`PATCH /v1/apps/current`

A given origin_url is validated (https, public hostname, not an IP, not an Apexly host, not a domain of another app) and probed before it is saved; the response carries origin_reachable and origin_latency_ms. 422 origin_not_allowed when it resolves to a private, loopback, link-local, CGNAT or reserved address. Test keys are sandboxed: once the app has a live domain, a test key gets 403 forbidden (use a live key or the dashboard).

### Body

| Field | Type | Description |
| --- | --- | --- |
| `name` | `string` | At most 80 characters. |
| `origin_url` | `string` | https, scheme and host only; probed before it is saved. At most 2048 characters. |
| `webhook_url` | `string \| null` | https; stored, deliveries start in a later release. At most 2048 characters. |
| `whitelabel_host` | `string \| null` | e.g. domains.hireflow.com (Growth and above, or trial); verified separately; null turns white-label off. At most 253 characters. |
| `apex_redirect_default` | `string` | One of `none`, `www`. |

### Response

`200 OK`. Errors use the [error envelope](/docs/api/errors).

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | app_… |
| `name` | `string` |  |
| `origin_url` | `string \| null` | Where every customer domain forwards, e.g. https://app.hireflow.com. |
| `origin_reachable` | `boolean` | Result of the latest probe. |
| `origin_latency_ms` | `integer \| null` | Latency of the latest successful probe. |
| `origin_checked_at` | `string \| null` | When the origin was last probed (RFC 3339). |
| `origin_status_reason` | `string \| null` | Why the latest probe failed: origin_not_allowed \| origin_dns_failed \| origin_timeout \| origin_tls_error \| origin_connection_failed \| origin_http_error \| origin_too_many_redirects \| origin_bad_redirect. |
| `origin_unreachable` | `boolean` | True after 3 consecutive failed probes (re-probed every 15 minutes). |
| `webhook_url` | `string \| null` |  |
| `whitelabel_host` | `string \| null` |  |
| `whitelabel_verified` | `boolean` |  |
| `whitelabel_target` | `string` | What whitelabel_host must CNAME to, e.g. edge.apexly.dev. |
| `whitelabel_status_reason` | `string \| null` | whitelabel_unverified while whitelabel_host is set but its CNAME chain does not reach whitelabel_target. One of `whitelabel_unverified`. |
| `whitelabel_found` | `string \| null` | The CNAME last seen at whitelabel_host while unverified (null = no record). |
| `whitelabel_checked_at` | `string \| null` | When whitelabel_host was last checked (every 6 hours once verified). |
| `whitelabel_grace_ends_at` | `string \| null` | Set when a verified host broke: domains routed through it keep serving until then, then go dns_broken. |
| `apex_redirect_default` | `string` | One of `none`, `www`. |
| `created_at` | `string` |  |

### Example

```bash tab="curl"
curl -X PATCH https://api.apexly.dev/v1/apps/current \
  -H "Authorization: Bearer $APEXLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"origin_url":"https://app.hireflow.com"}'
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/apps/current", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ origin_url: "https://app.hireflow.com" }),
});
const body = await res.json();
```

```python tab="Python"
import os
import requests

res = requests.patch(
    "https://api.apexly.dev/v1/apps/current",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
    json={"origin_url": "https://app.hireflow.com"},
)
body = res.json()
```

## Rotate the signing secret

`POST /v1/apps/current/signing-secret/rotate`

Issues a new whsec_ secret, returned only in this response. The previous secret keeps verifying for 24 hours (previous_valid_until). Needs a live key: test keys are sandboxed (403 forbidden).

### Response

`200 OK`. Errors use the [error envelope](/docs/api/errors).

| Field | Type | Description |
| --- | --- | --- |
| `signing_secret` | `string` | The new whsec_… secret. Returned only in this response. |
| `previous_valid_until` | `string` | The previous secret keeps verifying until then (24 h, RFC 3339). |

### Example

```bash tab="curl"
curl -X POST https://api.apexly.dev/v1/apps/current/signing-secret/rotate \
  -H "Authorization: Bearer $APEXLY_API_KEY"
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/apps/current/signing-secret/rotate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
  },
});
const body = await res.json();
```

```python tab="Python"
import os
import requests

res = requests.post(
    "https://api.apexly.dev/v1/apps/current/signing-secret/rotate",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
)
body = res.json()
```
