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

# How to get platform credentials

> Request a client_id and client_secret from Clink, and learn which integration each of the three registration methods (Pre-registration, CIMD, and DCR) applies to.

All three integration methods (MCP, RESTful API, and Vault SDK) first require a `client_id` from Clink. When your platform server calls Clink APIs, it also needs a `client_secret`. This page explains how to apply, what Clink registers, and which integration each of the three registration methods applies to. After you get the credentials, return to the matching integration guide to continue: [How to integrate MCP](https://docs.clinkbill.com/guides/agent/platform_integration/mcp_integration.md), [How to integrate RESTful API](https://docs.clinkbill.com/guides/agent/platform_integration/restful_api.md), or [How to integrate Vault SDK](https://docs.clinkbill.com/guides/agent/platform_integration/vault_sdk.md).

## Choose a registration method

| Registration method | What you get | Supported integration methods |
| - | - | - |
| **Pre-registration** (recommended) | A `client_id` and `client_secret` issued by Clink | MCP, RESTful API, Vault SDK |
| **CIMD** | A public `client_id` (the URL of the metadata file), with no `client_secret` | MCP only |
| **DCR** | A dynamically registered `client_id`, with no `client_secret` | MCP only |

When the platform server calls `/platform/sessions`, the Portal API, or Vault, it must exchange the `client_secret` for a platform token. Therefore, RESTful API and Vault SDK can only use Pre-registration, and a platform client cannot be self-created through DCR. CIMD and DCR are only for scenarios where you build your own MCP Host and each user completes standard OAuth authorization directly.

## Pre-registration (recommended)

Clink registers the client and issues credentials for you in the target environment. Clink issues credentials separately for each environment: Sandbox UAT (`https://uat-api.clinkbill.com`) and Production (`https://api.clinkbill.com`) credentials cannot be used interchangeably.

### Provide to Clink

* Application name, technical contact, and target merchant scenarios.
* Deployment information for Sandbox UAT and Production.
* The fixed HTTPS `redirect_uri` used for first-time user authorization. Required for MCP and RESTful API; not required for Vault SDK.
* The integration methods and capabilities you plan to use. Clink registers scopes accordingly; see the table below.
* Recommended: the platform RSA public key. See [Register an RSA public key](#rsa-public-key).

### Issued by Clink

| Integration method | Credentials | Registered scopes |
| - | - | - |
| MCP | Platform `client_id` and `client_secret` | Platform scope `agent-platform:account`, plus the user-token MCP scopes configured uniformly based on platform capabilities. See [Scope configuration](https://docs.clinkbill.com/guides/agent/platform_integration/mcp_integration.md#scopes) |
| RESTful API | Shares the same platform client with MCP | Platform scope `agent-platform:account`, plus Portal scopes `portal:read portal:write` |
| Vault SDK | A separate Vault `client_id` and `client_secret` | `vault:session vault:pay vault:read` |

If you integrate both MCP and RESTful API, you need only one platform client. Vault SDK credentials are issued separately and cannot be mixed with the platform client.

If you build your own MCP Host and only need a public client, you can also ask Clink to register only a `client_id` without issuing a `client_secret`. This kind of client uses the same authorization flow as CIMD and DCR. See [Initiate user authorization](#public-client-authorization).

### Register an RSA public key

If you want payment credentials returned as an encrypted `key` / `payload`, contact Clink offline to register an RSA public key in PEM X.509 SubjectPublicKeyInfo format (`BEGIN PUBLIC KEY`) for each environment. Public key registration and client registration are two separate steps.

* MCP's `get_credential` and the RESTful API's `POST /agent/platform/credential` both use this public key. Vault SDK does not need it.
* For the RESTful API, if no public key is registered and the server has not enabled plaintext mode, the credential endpoint returns `71211012` (`credential_public_key_not_configured`). Registration is recommended for Production.
* Keep the private key only in trusted platform components. For decryption, see [Encrypted credential decryption](https://docs.clinkbill.com/guides/agent/browser_pay/decryption.md).

### Store credentials

Your backend needs to store:

* `CLINK_CLIENT_ID` and `CLINK_CLIENT_SECRET`. If you also integrate Vault SDK, store a separate set of Vault credentials.
* The exact `redirect_uri` registered for the platform.
* The RSA private key (if you registered a public key).

Keep the `client_secret` and RSA private key only on a trusted server. Do not put them in browser code, URLs, logs, Agent input, or ordinary business messages. Use only one set of platform credentials per environment, shared by all users. Do not request a new client for each user or each request.

## CIMD

MCP only. Suitable for MCP Hosts that can host a public JSON file under their own HTTPS domain. Host the file and use the file URL as the `client_id`:

```json theme={null}
{
  "client_id": "https://agent.example.com/.well-known/oauth-client.json",
  "client_name": "Example Agent",
  "redirect_uris": ["https://agent.example.com/oauth/clink/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "wallet:read wallet:setup payment:execute instruction:read instruction:write refund:read refund:write events:read events:consume offline_access"
}
```

Clink fetches this file to validate authorization requests. The file must meet these requirements:

* The URL uses HTTPS and includes a path, with no query or fragment.
* The `client_id` in the file exactly matches the file URL.
* The URL returns HTTP 200 directly with `Content-Type` set to `application/json`. Clink does not follow redirects.
* The file is no larger than 5 KB and contains no secrets.

## DCR

MCP only. Suitable when you cannot host a public HTTPS file, or when the Host only supports dynamic registration. First read `{API_BASE_URL}/.well-known/oauth-authorization-server`. You can use DCR only if it returns `registration_endpoint`:

```http theme={null}
POST {registration_endpoint}
Content-Type: application/json

{
  "client_name": "Example Agent",
  "redirect_uris": ["https://agent.example.com/oauth/clink/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "wallet:read wallet:setup payment:execute instruction:read instruction:write refund:read refund:write events:read events:consume offline_access"
}
```

Persist the returned `client_id`. Clink does not support modifying a registered client: to change the redirect URI or scopes, register a new client, and users must re-authorize with the new `client_id`.

## Common rules for CIMD and DCR

* Both are public clients without a `client_secret`, and must use Authorization Code + PKCE (S256).
* The registered scopes are the upper limit for every later authorization request. Requests that exceed them return `invalid_scope`, so register every scope the Agent might use.
* Register only once per deployment, tenant, or installation, and reuse the same `client_id` for all users.
* Without a `client_secret`, you cannot call `/platform/sessions`. After you get a `client_id`, initiate user authorization yourself, as described below.

### Initiate user authorization

1. Read `{API_BASE_URL}/.well-known/oauth-protected-resource/mcp` and get the issuer from `authorization_servers`.
2. Read `{issuer}/.well-known/oauth-authorization-server` to get `authorization_endpoint` and `token_endpoint`. Do not hard-code the endpoints.
3. Generate and temporarily store `state` and a PKCE `code_verifier` for the current user, and compute `code_challenge` with S256.
4. Redirect the user to `authorization_endpoint`, with all parameters URL-encoded:

```text theme={null}
response_type=code
client_id={CLIENT_ID}
redirect_uri=https://agent.example.com/oauth/clink/callback
scope=wallet:read payment:execute instruction:read instruction:write events:read events:consume offline_access
resource={MCP_URL}
state={RANDOM_STATE}
code_challenge={S256_CODE_CHALLENGE}
code_challenge_method=S256
```

For callback validation and token exchange, see [Agent Platform MCP Login](https://docs.clinkbill.com/api-reference/mcp/agent_platform_login.md), replacing `client_id` with the public client value you obtained. Then configure the system prompt and MCP as described in steps 2 and 3 of [How to integrate MCP](https://docs.clinkbill.com/guides/agent/platform_integration/mcp_integration.md). When you receive `403 insufficient_scope`, read the required scopes from the `scope` parameter of the `WWW-Authenticate` response header, merge them with the granted scopes, and have the user re-authorize. The merged result cannot exceed the registered scopes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.