---
title: "Create Permission"
method: POST
path: "/x402/permissions"
tags: ["X402 - Permissions"]
---

# Create Permission

`POST /x402/permissions`

## Request

- Base URL: `https://api.sandbox.nevermined.app/api/v1`
- URL: `https://api.sandbox.nevermined.app/api/v1/x402/permissions`
- Auth: HTTP bearer

Creates a delegated permission and generates an x402 access token.

## Request body

- CreatePermissionRequest: Body of `POST /x402/permissions` (`GenerateX402TokenDto`) — an x402 PaymentPayload. `accepted` is the only field REQUEST VALIDATION requires: the handler runs a `ValidationPipe`, so a body without it is rejected with 400 before any handler logic runs. It is not the only field the API requires — every scheme handler additionally demands `delegationConfig` and `accepted.planId`, refusing the mint with `BCK.X402.0030` (HTTP 402). There is no settlement-account field: for card schemes the seller's Stripe Connect account is resolved server-side from the plan and is never supplied by the caller.
  - `resource` X402Resource: x402 protected-resource descriptor (`X402ResourceDto`). The same shape appears in the server's 402 `paymentRequired` and in the payload you mint at `POST /x402/permissions`.
    - `url` string, required: URL of the protected resource or endpoint.
    - `description` string: Human-readable description of the resource.
    - `mimeType` string: Expected response MIME type.
  - `accepted` X402Scheme, required: One x402 payment scheme (`X402SchemeDto`). The same shape appears in `accepts[]` on the server's 402 response and in `accepted` on the payload you mint — the client echoes back the scheme it selected.
    - `scheme` 'nvm:erc4337' | 'nvm:card-delegation', required: Payment scheme identifier. Selects the settlement rail: `nvm:erc4337` settles on-chain, `nvm:card-delegation` settles against an enrolled card.
    - `network` string, required: Settlement RAIL, not the environment. Card flows send `stripe`, `braintree` or `visa`; crypto flows send `eip155:<chainId>`. An environment name such as `sandbox` or `live` is rejected by request validation.
    - `planId` string: Plan id (256-bit identifier). Required for BOTH schemes — a mint without it is refused with `BCK.X402.0030` (HTTP 402). Request validation does not enforce it for either scheme: the DTO marks it optional, so the rejection comes from the scheme handler rather than from the `ValidationPipe`.
    - `extra` X402SchemeExtra: Scheme-specific extra fields (`X402SchemeExtraDto`). Every field is optional. On `tokenVersion` 3, `agentId` and `httpVerb` are signed as the empty string when omitted — which binds the token to that value being ABSENT rather than to any value. `version` is not part of the v3 signed struct at all, so omitting it binds nothing.
      - `version` string: Scheme version.
      - `agentId` string: Agent id the token is bound to, used for endpoint validation.
      - `httpVerb` string: HTTP verb the token is bound to, used for endpoint validation.
  - `delegationConfig` X402DelegationConfig: Delegation options for `POST /x402/permissions` (`DelegationConfigDto`), used by both schemes. The supported flow is create-first: create the delegation with `POST /delegation/create`, then send only `delegationId` here. The inline create-on-the-fly fields are deprecated — they still work and emit a runtime warning.
    - `delegationId` string, uuid: Existing delegation to reuse — the supported create-first path. Must be a v4 UUID; a non-v4 id is a request-format error, not an authentication or not-found failure.
    - `apiKeyId` string: Nevermined API key id (`skId`) to restrict this delegation to. Omit so that any key can use it. Applied only when THIS request creates the delegation inline; it is ignored when you pass `delegationId`, where the restriction is read off the stored delegation instead.
    - `providerPaymentMethodId` string: DEPRECATED — inline create-on-the-fly. Stripe payment method id from SetupIntent confirmation. Prefer create-first, then pass only `delegationId`.
    - `cardId` string: DEPRECATED — inline create-on-the-fly. Payment-method entity UUID, an alternative to `providerPaymentMethodId`. Prefer create-first, then pass only `delegationId`.
    - `spendingLimitCents` integer: DEPRECATED — inline create-on-the-fly. Maximum spend in the smallest currency unit.
    - `durationSecs` integer: DEPRECATED — inline create-on-the-fly. Lifetime of the delegation in seconds.
    - `currency` 'usd' | 'eur' | 'usdc' | 'eurc': DEPRECATED — inline create-on-the-fly. ISO 4217 lowercase currency code. Has no default: it is required when creating inline.
    - `maxTransactions` integer: DEPRECATED — inline create-on-the-fly. Maximum number of transactions allowed. Omit for unlimited.
  - `tokenVersion` 2 | 3: EIP-712 struct version to sign. A version 3 signature carries a one-time nonce, so the token is SINGLE-USE — it is consumed by its first settle and a second settle is refused with `BCK.X402.0059`; mint one token per paid request. A version 3 token is also bound to whichever of `accepted.extra.agentId`, `resource.url` and `accepted.extra.httpVerb` you send on this request, since each is signed as the empty string when omitted. Version 2 is the legacy shape: reusable and unbound, so a captured token replays until the permission or delegation is revoked — ask for it only if you cannot mint per request. When this field is omitted the server signs version 3, except for clients whose pinned API version is below 1.34 — that pin comes from the `Nevermined-Version` header, or, when no header is sent, from the version stamped on the API key when it was minted — which keep receiving version 2.

## Response `201`

Permission created

- PermissionCreatedResponse: Response of `POST /x402/permissions`. The endpoint returns the access token and nothing else — it does not return the permission hash, so read the new permission back off `GET /x402/permissions`.
  - `accessToken` string, required: x402 access token (JWT) for permission-based access. Used by the subscriber to call agent endpoints without exposing their private keys. The permission details (plan id, agent id, subscriber address, expiry, limits) are embedded in the token.

## Other responses

- `401`: Unauthorized
- `402`: Insufficient balance

---

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