> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dr.green/llms.txt
> Use this file to discover all available pages before exploring further.

# 03 environment

# Environment & Base URLs

> **TL;DR.** Production is `https://api.drgreennft.com/api/v1`. Staging exists at `https://stage-api.drgreennft.com/api/v1` but its uptime is intermittent — don't depend on it for live demos. Every authenticated request needs the headers in [§ Required headers](#required-headers).

***

## Environments

| Environment    | Base URL                                  | Use for                                          | Status (10 May 2026)                         |
| -------------- | ----------------------------------------- | ------------------------------------------------ | -------------------------------------------- |
| **Production** | `https://api.drgreennft.com/api/v1`       | Live customer traffic, real orders, real payouts | ✅ Healthy                                    |
| **Staging**    | `https://stage-api.drgreennft.com/api/v1` | Pre-prod testing against real-shape data         | ❌ 503 (upstream connect error / Envoy proxy) |

> ⚠️ **Staging is currently unreachable.** Health check returns `HTTP 503` with an Envoy upstream-connect-error. This was first observed during research on 8 May and remained on 10 May. If you need staging access, ping the Dr Green backend team to bring it back up.

The spec does **not** declare a `servers` array (verified against `/api-json`), so client generators (`openapi-generator`, etc.) will require you to inject the base URL manually. The enriched OpenAPI 3.1 spec in this repo (`openapi/drgreen-api.yaml`) adds an explicit `servers` block.

***

## Companion URLs

| Resource              | URL                                   | Purpose                                                   |
| --------------------- | ------------------------------------- | --------------------------------------------------------- |
| **Live OpenAPI spec** | `https://api.drgreennft.com/api-json` | OpenAPI 3.0.0 source-of-truth, served publicly, no auth   |
| **Swagger UI**        | `https://api.drgreennft.com/api`      | Browse endpoints in a browser                             |
| **DAPP web UI**       | `https://dapp.drgreennft.com`         | Where holders log in to manage NFTs and generate API keys |

***

## Health check

A single unauthenticated endpoint for liveness probes:

```bash theme={null}
curl https://api.drgreennft.com/api/v1/public/healthStatus
# → {"success":true,"statusCode":200,"message":"Success","data":"Success"}
```

Use this in your deployment pipeline before flipping store traffic over.

***

## Required headers

Every authenticated request to a `/dapp/...` endpoint must include three headers:

| Header             | Value                                                            | Notes                                                                   |
| ------------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `x-auth-apikey`    | Holder's Base64-encoded PEM SPKI public key                      | The `apiKey` returned by `POST /keys`                                   |
| `x-auth-signature` | Base64-encoded ECDSA-SHA256 signature over the canonical payload | See [02-authentication.md](./02-authentication.md)                      |
| `Content-Type`     | `application/json`                                               | Required for every `POST`, `PATCH`, `PUT`. Optional for `GET`/`DELETE`. |

**Auth model.** The same endpoints accept either a valid Passport JWT (used by the DAPP UI) **or** the `x-auth-apikey` + `x-auth-signature` pair (used by external integrators like your store). This is implemented server-side as `DualAuthGuard`. Don't send both — pick one and stick with it for the request.

***

## Content-Type rules

The backend uses Express's body-parser, which is strict about Content-Type for JSON parsing.

| Method   | Body required? | Content-Type required?       |
| -------- | -------------- | ---------------------------- |
| `POST`   | Yes            | **Yes** — `application/json` |
| `PATCH`  | Yes            | **Yes** — `application/json` |
| `PUT`    | Yes            | **Yes** — `application/json` |
| `GET`    | No             | Optional                     |
| `DELETE` | No             | Optional                     |

> **Common gotcha.** If you sign a JSON body but forget the `Content-Type: application/json` header, the server's body-parser leaves the body as a raw string and your signature won't match what the server reproduces. Always send the header on writes.

JSON formatting matters for signing. Express's body-parser produces compact JSON (no whitespace between `,` `:` separators) when reproducing the canonical payload server-side. **Sign the exact string you'll send on the wire.** See [02-authentication.md § Canonical payload](./02-authentication.md) for the rules per HTTP method.

***

## Rate limits

Not currently enforced at the API gateway level (verified against backend source as of 8 May 2026 — no rate-limiter middleware registered globally in `app.module.ts`). 🔒 *Subject to change without notice — assume polite throttling will be enforced at some point and engineer your store accordingly.*

Recommended client-side guidance:

* Background polling: no faster than 1 req/sec per holder
* Order status checks: cache for 30s minimum
* Strain catalogue: cache for 5 minutes minimum (it changes infrequently)

***

## TLS, CORS, and IP allow-listing

* **TLS.** Production enforces HTTPS. HTTP requests redirect or fail.
* **CORS.** The backend allows requests from `dapp.drgreennft.com` and the marketplace front-ends. **Server-to-server calls from your store backend are not subject to CORS** — only browser-originated calls are. If you're calling from a customer's browser directly, your origin must be whitelisted; talk to Dr Green to add it.
* **IP allow-listing.** Not currently enforced. Discuss with Dr Green if your hosting provider rotates outbound IPs and you need a stable identity beyond the API key signature.

***

## Versioning

The current and only version is `v1`, baked into the path (`/api/v1/...`). When `v2` ships, both will run in parallel; you'll get advance notice via the Dr Green changelog. The `info.version` field in the live OpenAPI spec is `1.0` and increments on backend deploys — that's the **deploy version**, not the API contract version.
