---
title: "Register"
method: POST
path: "/oauth/register"
tags: ["oauth"]
---

# Register

`POST /oauth/register`

## Request

- Base URL: `https://app.zeno-works.ch` (the document declares no server; this is the origin it was published from)
- URL: `https://app.zeno-works.ch/oauth/register`
- Auth: none declared

RFC 7591 dynamic client registration. **Off unless ``OAUTH_ALLOW_DCR`` says so.**

It is an unauthenticated write endpoint, and registration grants nothing on its own —
but a registered ``client_name`` is rendered to a human on the consent screen, which
makes it a phishing surface: an attacker registers "Zeno Support", builds an authorize
URL, and mails it. CIMD is preferred precisely because the ``client_id`` is then a URL
whose **origin** the consent screen can show, which is a signal the attacker cannot
forge.

Each redirect URI must be ``https://<host>…``, an ``http://`` loopback URI
(``127.0.0.1``, ``[::1]`` or ``localhost``; its port may differ at use time), or a known
desktop client's own scheme and host — today only Cursor's
``cursor://anysphere.cursor-mcp/…`` (matched exactly). No userinfo, fragment, backslash or
whitespace.

Mounted at ``/oauth/register``, not ``/register`` — the gateway leaves that path to the
SPA on purpose (``api-routes.conf``: "a plausible future SPA route, and a gateway 404
would silently shadow it").

## Request body

- ClientRegistrationIn: RFC 7591, the subset this server accepts.
  - `client_name` string
  - `redirect_uris` string[], required

## Response `200`

Successful Response

- ClientRegistrationOut
  - `client_id` string, required
  - `client_name` string, required
  - `redirect_uris` string[], required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/zeno-works/apis/zeno-api.md) · [All operations](https://skmtc.dev/zeno-works/apis/zeno-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zeno-works/apis/zeno-api/revisions/1eb93dde146c?raw)
