---
title: "Dynamic Client Registration"
method: POST
path: "/oauth/register"
tags: ["OAuth"]
---

# Dynamic Client Registration

`POST /oauth/register`

## Request

- Base URL: `https://api.purplegrain.com`
- URL: `https://api.purplegrain.com/oauth/register`
- Auth: none declared

**RFC 7591** Dynamic Client Registration. One unauthenticated endpoint that
lets any compliant OAuth/MCP client self-register and receive its own
`client_id`, so AI chatbots (ChatGPT, Claude, Cursor, …) onboard with zero
manual configuration.

Registration alone grants no data access: a registered client can only reach
resources after a Purple Grain user completes the interactive
`GET /oauth/authorize` login + consent (PKCE is enforced). Most clients
should register as public (`token_endpoint_auth_method=none`).

## Request body

- ClientRegistrationRequest: RFC 7591 Dynamic Client Registration request metadata.
  - `client_name` string: Human-readable client name. Defaults to "MCP client" when omitted.
  - `redirect_uris` string[], required: Redirect URIs (max 5). Each must be `https`, an RFC 8252 loopback `http` URI (localhost / 127.0.0.1 / ::1), or a native private-use scheme (e.g. `com.example.app:/cb`). Plain `http` on a remote host is rejected.
  - `token_endpoint_auth_method` 'none' | 'client_secret_basic' | 'client_secret_post': `none` registers a public client (PKCE, no secret) — the default and the norm for MCP clients. Any other value registers a confidential client and a `client_secret` is returned.
  - `scope` string: Space-separated requested scopes. `public`, `read` and `write` are honored; unknown scopes are dropped. Defaults to `public read write`: an assistant connection starts with read and write where the person's role allows it, limited by the per-business grants they can narrow.
  - `application_type` string
  - `grant_types` string[]
  - `response_types` string[]

## Response `201`

Client registered.

- ClientRegistrationResponse: RFC 7591 Dynamic Client Registration response.
  - `client_id` string
  - `client_id_issued_at` integer: Issuance time (seconds since the Unix epoch).
  - `client_secret` string: Present only for confidential clients (token_endpoint_auth_method other than `none`).
  - `client_secret_expires_at` integer: 0 = never expires (RFC 7591). Present only for confidential clients.
  - `redirect_uris` string[]
  - `token_endpoint_auth_method` string
  - `grant_types` string[]
  - `response_types` string[]
  - `client_name` string
  - `scope` string

## Other responses

- `400`: Invalid client metadata or redirect URI.

---

[API](https://skmtc.dev/purplegrain/apis/purple-grain-api.md) · [All operations](https://skmtc.dev/purplegrain/apis/purple-grain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/purplegrain/apis/purple-grain-api/revisions/4bedbc1c784c?raw)
