# Internal API

URL: https://zerodev.ca/docs/prism/developer-documentation/internal-api

> How the web app talks to Prism's API, who a request acts as, and how permissions are checked.



Prism runs two servers. The web server on port `3000` serves the store, the dashboard and sign-in. The API on port `3001` holds every route, including your module's. The web server never touches module data directly. It calls the API for everything.

## Requests From the Web App

When the web server calls the API it sends Prism's internal secret plus headers that say who is signed in:

| Header                                        | What it carries                             |
| --------------------------------------------- | ------------------------------------------- |
| `Authorization: Bearer <secret>`              | Prism's internal secret from `config.json`. |
| `x-actor-kind`                                | `staff` or `customer`.                      |
| `x-actor-id`, `x-actor-name`, `x-actor-email` | The user.                                   |
| `x-actor-permissions`                         | Their permissions as a JSON array.          |
| `x-actor-discord`                             | Their Discord ID, if linked.                |
| `x-actor-ip`                                  | Their real IP address.                      |

The API trusts these headers only alongside the secret. Keep the secret private, since anything holding it can act as any user.

This happens in four places:

| Where                             | Path                                                                                 |
| --------------------------------- | ------------------------------------------------------------------------------------ |
| Your page's `load()`              | `client.send("GET", "/api/modules/<module>/<path>")`                                 |
| Resource pages and your own views | `request(module, path)`, which goes through `/api/m/<module>/<path>` on the web port |
| The store                         | `/api/v1/` on the web port, forwarded to the API as is                               |
| Prism's own pages                 | Built-in routes such as `/api/settings` and `/api/audit`                             |

In each case the request reaches your route as that user, so you never handle sessions yourself.

## Actors

Every request gets an actor on `request.actor`:

| Kind       | From                                                                               |
| ---------- | ---------------------------------------------------------------------------------- |
| `system`   | The secret with no actor headers, such as Prism's own calls. Has every permission. |
| `staff`    | A signed-in team member.                                                           |
| `customer` | A signed-in user with no role.                                                     |
| `token`    | An API token from the **API Tokens** page. Its permissions are the token's scopes. |
| `public`   | Nobody, on a route with `access: "public"`. Has no permissions.                    |

A private route with no valid secret or token answers `401`. A token that does not match is written to the audit log.

## Checking Permissions

Routes check permissions for you through their `permissions` option. To check by hand:

```js
if (!this.prism.api.allowed(request.actor, "products.edit")) this.fail(403, this.prism.modules.lang.phrase("example", "messages", "denied"));
```

| Actor has         | Passes                                 |
| ----------------- | -------------------------------------- |
| `*`               | Everything.                            |
| `products.edit`   | `products.edit`.                       |
| `products.*`      | Any `products.` permission.            |
| `products.manage` | Any `products.` permission, for staff. |

`customer` is a special permission that only customers and the system pass. Public actors fail every check except an empty one.

## Request Helpers

| Helper                                      | What it does                                                                                              |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `this.prism.api.allowed(actor, permission)` | The check above.                                                                                          |
| `this.prism.api.ip(request)`                | The caller's IP. Reads `x-actor-ip` from the web server, then `cf-connecting-ip`, then `x-forwarded-for`. |
| `this.prism.api.address()`                  | The public API address from **API URL**, or `http://localhost:3001`.                                      |
| `this.prism.web.address()`                  | The public site address from **Web URL**, or `http://localhost:3000`. Use it for links you give out.      |

## Built-in Routes

These belong to Prism rather than a module. They all need the secret except the first three.

| Route                                                           | What it does                                                                             |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `GET /api/status`                                               | Version, whether Prism is running and configured, database and module state.             |
| `GET /api/health`                                               | `200` when Prism is running with the database up and no failed modules, otherwise `503`. |
| `GET /api/v1/public-key`                                        | The Ed25519 public key used to sign responses.                                           |
| `GET /api/permissions`                                          | Every permission, from Prism and each module.                                            |
| `GET /api/modules`, `POST /api/modules/toggle`                  | List modules and turn them on or off.                                                    |
| `GET /api/pages`                                                | Every module page.                                                                       |
| `GET /api/modules/configs`, `POST /api/modules/config`          | Read and save [config](/docs/prism/developer-documentation/configuration) groups.        |
| `GET /api/locales`, `GET /api/modules/dictionary`               | Languages and the merged web dictionary.                                                 |
| `GET /api/modules/langs`, `POST /api/modules/lang`              | Read and save [lang](/docs/prism/developer-documentation/languages) text.                |
| `POST /api/translate`                                           | Translate text for the Lang page.                                                        |
| `GET /api/settings`, `POST /api/settings`                       | Prism's settings, with secrets hidden.                                                   |
| `POST /api/settings/reload`, `POST /api/restart`                | Reload settings from the database, or restart Prism.                                     |
| `POST /api/signing/rotate`                                      | Make a new response signing key.                                                         |
| `GET /api/config`, `POST /api/config`                           | Server ports and URLs.                                                                   |
| `GET /api/tokens`, `POST /api/tokens`, `DELETE /api/tokens/:id` | API tokens.                                                                              |
| `GET /api/audit`                                                | The audit log.                                                                           |
| `GET /api/logs`                                                 | Recent console lines.                                                                    |

Your module's routes live under `/api/modules/<module>`, or at their own path when they set `absolute: true`. See [Routes](/docs/prism/developer-documentation/routes).
