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

# Request templates

> Start from a tested Request policy for user-owned wallets: allowances, known recipients, co-signers, adjustable limits and message signing.

export const PermissionsCards = ({basePath, pages, cols = 2, horizontal = false}) => {
  const ImageCard = Card;
  const hrefOverrides = {
    "/v3/react/guides/permissions": {
      "conditional-approvals": "/v3/react/guides/conditional-approvals"
    },
    "/v3/rest/permissions": {
      "backend": "/v3/rest/permissions-administration"
    }
  };
  const guardrailBases = ["/v3/rest/permissions", "/v3/server/guides/permissions"];
  const ownership = guardrailBases.includes(basePath) ? 'guardrail' : 'request';
  const overviewImages = {
    "/v3/rest/permissions": {
      "imgUrl": "/images/v3/cards/rest-guardrails.png",
      "horizontalImgUrl": "/images/v3/cards/rest-guardrails-horizontal.png"
    },
    "/v3/server/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-server-guardrail-signing.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-server-guardrail-signing-horizontal.png"
    },
    "/v3/react/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    },
    "/v3/react-native/guides/permissions": {
      "imgUrl": "/images/v3/cards/sdk-get-policy-consent-url.png",
      "horizontalImgUrl": "/images/v3/cards/sdk-get-policy-consent-url-horizontal.png"
    }
  };
  const registry = {
    overview: {
      title: "Permissions overview",
      description: "Return to the start of the Permissions path.",
      ...overviewImages[basePath]
    },
    "developer-portal": {
      title: "Create policies in the Developer Portal",
      description: "Build a policy with the Portal forms and activate it on a beta key.",
      imgUrl: "/images/v3/cards/developer-portal-policy-form.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-form-horizontal.png"
    },
    "json": {
      title: "Write policy JSON",
      description: "Move to JSON for policies the forms cannot express.",
      imgUrl: "/images/v3/cards/developer-portal-policy-json.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-json-horizontal.png"
    },
    "testing": {
      title: "Test your policies",
      description: "Exercise every rule on beta before you ship.",
      imgUrl: "/images/v3/cards/concept-policy-testing.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-testing-horizontal.png"
    },
    "production": {
      title: "Go to production",
      description: "Request a production review and publish your policy.",
      imgUrl: "/images/v3/cards/concept-policy-publication.png",
      horizontalImgUrl: "/images/v3/cards/concept-policy-publication-horizontal.png"
    },
    "conditional-approvals": {
      title: "Conditional approvals",
      description: "Require people to approve a request before it signs.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "approval-signatures": {
      title: "Collect approval signatures",
      description: "Collect signatures from approvers for multisig workflows.",
      imgUrl: "/images/v3/cards/sdk-get-approval-signatures.png",
      horizontalImgUrl: "/images/v3/cards/sdk-get-approval-signatures-horizontal.png"
    },
    "adjustable-parameters": {
      title: "Adjustable parameters",
      description: "Let users set their own limits and managers adjust approval settings.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "lifecycle": {
      title: "Manage the policy lifecycle",
      description: "Version, activate, replace and retire policies.",
      imgUrl: "/images/v3/cards/developer-portal-policy-versions.png",
      horizontalImgUrl: "/images/v3/cards/developer-portal-policy-versions-horizontal.png"
    },
    "backend": {
      title: "Manage permissions from your backend",
      description: "Assign approvers and read policy state with your server secret.",
      imgUrl: "/images/v3/cards/rest-permissions-administration.png",
      horizontalImgUrl: "/images/v3/cards/rest-permissions-administration-horizontal.png"
    },
    templates: ownership === "guardrail" ? {
      title: "Guardrail templates",
      description: "Start from a tested Guardrail policy.",
      imgUrl: "/images/v3/cards/concept-guardrail-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-guardrail-templates-horizontal.png"
    } : {
      title: "Request templates",
      description: "Start from a tested Request policy.",
      imgUrl: "/images/v3/cards/concept-request-templates.png",
      horizontalImgUrl: "/images/v3/cards/concept-request-templates-horizontal.png"
    },
    "guardrail:templates/spending-caps": {
      title: "Spending caps",
      description: "Cap native and token transfers per transaction or per day.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "guardrail:templates/allowlists": {
      title: "Recipient and contract allowlists",
      description: "Limit transfers and contract calls to addresses you know.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "guardrail:templates/approval-tiers": {
      title: "Approval thresholds and tiers",
      description: "Hold large transfers for approval, or deny the largest.",
      imgUrl: "/images/v3/cards/concept-approval-tiers.png",
      horizontalImgUrl: "/images/v3/cards/concept-approval-tiers-horizontal.png"
    },
    "guardrail:templates/treasury": {
      title: "Treasury approvals",
      description: "Deny unplanned actions and approve wallet or Safe payouts in stages.",
      imgUrl: "/images/v3/cards/concept-treasury-approvals.png",
      horizontalImgUrl: "/images/v3/cards/concept-treasury-approvals-horizontal.png"
    },
    "guardrail:templates/message-signing": {
      title: "Message and raw signing",
      description: "Block or hold raw signatures, and block permits.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    },
    "request:templates/allowances": {
      title: "Transfer allowances",
      description: "Let small transfers and a daily budget sign without a prompt.",
      imgUrl: "/images/v3/cards/concept-spending-limits.png",
      horizontalImgUrl: "/images/v3/cards/concept-spending-limits-horizontal.png"
    },
    "request:templates/recipients-and-contracts": {
      title: "Known recipients and app contracts",
      description: "Cover transfers to known addresses and your contract's calls.",
      imgUrl: "/images/v3/cards/concept-recipient-allowlists.png",
      horizontalImgUrl: "/images/v3/cards/concept-recipient-allowlists-horizontal.png"
    },
    "request:templates/cosigner-approval": {
      title: "Co-signer approval",
      description: "Send large transfers to a co-signer for approval.",
      imgUrl: "/images/v3/cards/portal-conditional-approval-case.png",
      horizontalImgUrl: "/images/v3/cards/portal-conditional-approval-case-horizontal.png"
    },
    "request:templates/adjustable-limits": {
      title: "User-adjustable limits",
      description: "Let each user choose their own spending limits.",
      imgUrl: "/images/v3/cards/portal-user-policy-limits.png",
      horizontalImgUrl: "/images/v3/cards/portal-user-policy-limits-horizontal.png"
    },
    "request:templates/message-signing": {
      title: "Message signing",
      description: "Sign messages from users' wallets without a prompt.",
      imgUrl: "/images/v3/cards/concept-signing-actions.png",
      horizontalImgUrl: "/images/v3/cards/concept-signing-actions-horizontal.png"
    }
  };
  const entryFor = slug => registry[slug] || registry[`${ownership}:${slug}`];
  const hrefFor = slug => {
    if (slug === 'overview') return basePath;
    const overrides = hrefOverrides[basePath] || ({});
    return overrides[slug] || `${basePath}/${slug}`;
  };
  return <CardGroup cols={cols}>
      {pages.map(slug => {
    const entry = entryFor(slug);
    return <ImageCard key={slug} title={entry.title} description={entry.description} href={hrefFor(slug)} imgUrl={horizontal ? entry.horizontalImgUrl : entry.imgUrl} horizontal={horizontal} />;
  })}
    </CardGroup>;
};

export const PermissionsScenarioContent = () => <p>Each scenario page has the policy JSON, sample signing requests with their results, and the values to change for your app.</p>;

Request templates are tested policies that ask the owners of user-owned wallets for standing access. Pick a scenario, adjust the addresses and amounts, and publish it on beta through the Developer Portal or the CLI. Try the consent screen there with test users before you request a production review, because every user sees it before your app gets standing access.

A Request describes what your app may do without prompting the user each time. Para shows it to the user on a consent screen, and the user chooses one of two options:

* **Approve** grants standing access. Signing requests that match an `allow` rule then sign without a prompt.
* **Manually approve each transaction instead** keeps the user in the loop. Each matching signing request opens Para's review window.

A signing request that no rule matches goes to the user for review, as it would without the Request. When the first matching signing request arrives before the user has decided, the consent screen opens ahead of the review for that request. Standing access starts with the next request once the user approves this one. If they reject this request, or an approver rejects its approval case, the standing access is cancelled too.

| Scenario | What the templates do | Developer Portal forms |
| - | - | - |
| Allowances | Let small ETH transfers and a daily USDC budget sign without a prompt | Yes |
| Recipients and contracts | Cover transfers to known addresses and calls to your app's contract | Yes |
| Co-signer approval | Send large transfers to a co-signer for approval | No, use JSON |
| Adjustable limits | Let the user choose their own transfer limits | No, use JSON |
| Message signing | Let your app sign messages from the user's wallet | No, use JSON |

<Info>
  The policy's `description` is the text users see on the consent screen, after your app name and "would like to". In the Developer Portal it is the **User consent request language** field. Write it as a short action, such as `Send up to 0.01 ETH per transfer on Base`.
</Info>

## Choose a scenario

<PermissionsScenarioContent />

<PermissionsCards basePath="/v3/react-native/guides/permissions" pages={["templates/allowances", "templates/recipients-and-contracts", "templates/cosigner-approval", "templates/adjustable-limits", "templates/message-signing"]} cols={3} />

## Use a template

Every template comes with a JSON policy. Templates the Developer Portal forms can express also list the form steps. Publish each one on your Development key, which runs on beta, and test it there first.

<Tabs>
  <Tab title="Developer Portal forms">
    Follow the template's **Developer Portal** tab. A policy saved from the forms gets generated policy and rule IDs, and its JSON can differ in small ways that the template points out. Compare it with the **Normalized policy JSON** on the **Review** step before you select **Save Draft**.
  </Tab>

  <Tab title="Developer Portal JSON editor">
    1. On your **Development** key, open **Permissions**, select the **Guardrails** or **Requests** tab, and select **Add**. Once the tab lists policies, the button is **New Guardrail** or **New Request**.
    2. Enter a name, select the networks the template's `selector` names, and select **Continue**.
    3. Select the **JSON** tab, then **Edit JSON**.
    4. Replace everything in **Policy JSON** with the template and select **Review**. Para validates the policy before anything is saved, and the template's `metadata.description` replaces the name you entered.
    5. Select **Save Draft**, then **Activate** on the draft.
  </Tab>

  <Tab title="CLI">
    Save the template to a file, then validate it, create a draft and activate it on your beta key:

    ```bash theme={null}
    para keys permissions validate KEY_ID --file policy.json --environment beta
    para keys permissions create KEY_ID --file policy.json --environment beta
    para keys permissions activate RECORD_ID KEY_ID --environment beta
    ```

    `create` prints the draft's record ID and the exact `activate` command to run.
  </Tab>
</Tabs>

<Note>
  If your key already has a policy of the same type on the same networks, the Developer Portal opens that policy for editing, and the page title changes to **Edit Guardrail Policy** or **Edit Request Policy**. The editor holds that policy's JSON with the next `version` filled in. Merge the template's rules into it and keep its `id`, selector and `version`, because pasting the template over it fails with `policy_record_identity_conflict`, `policy_record_selector_conflict` or `policy_record_version_conflict`. The button there is **Save changes**, and an active policy enforces the merged rules as soon as you save.
</Note>

## Conventions

The templates share a few conventions. Keep them when you adapt a template, or validation fails.

### Amounts

Amounts are strings of whole base units, such as `"1000000"`. A JSON number fails validation with `value_type_mismatch`.

| Asset | Decimals | 1 unit in base units |
| - | - | - |
| ETH (wei) | 18 | `1000000000000000000` |
| USDC on EVM networks | 6 | `1000000` |
| SOL (lamports) | 9 | `1000000000` |
| XLM (stroops) and Stellar assets such as USDC | 7 | `10000000` |

### Addresses

Para lowercases EVM addresses before it compares them, so checksummed and lowercase addresses match. The templates use lowercase, as the Developer Portal does. Other wallet types need each network's canonical form: a Solana base58 key as is, a Stellar `G…` account in upper case, and a Sui `0x` address with 64 lowercase hex characters.

### Networks

`chainId` in the selector picks the networks a policy covers. Omit it to cover every network of the wallet type. A personal message and a raw signature carry no network, and the Para SDKs sign typed data and authorizations as messages, so the message signing templates leave `chainId` out. The treasury templates leave it out as well and check the network through each asset value, such as `eip155:8453:native`. The other templates use mainnets. To test with testnet funds, swap in the testnet everywhere the template names the network, including asset values and token addresses.

| Wallet type | Templates use | Testnet | Accepted forms |
| - | - | - | - |
| EVM | `8453` (Base) | `84532` (Base Sepolia), where USDC is `0x036cbd53842c5426634e7929541ec2318f3dcf7e` | Numeric chain ID or `eip155:<id>` |
| SOLANA | `solana:mainnet` | `solana:devnet` | `solana:mainnet`, `solana:devnet`, `solana:testnet` |
| STELLAR | `stellar:mainnet` | `stellar:testnet` | `stellar:mainnet`, `stellar:testnet` or the network passphrase, which the Developer Portal writes |

### IDs, versions and windows

Give each policy an `id` your key does not use yet. IDs that start with `para-` are reserved.

* Raise `version` when you publish a change to a policy.
* `window: "24h"` is a fixed daily window that resets at 00:00 UTC, not 24 hours after the first transfer. The Developer Portal writes windows in hours, and `1d` is the same window. A policy can use one window length per spend fact.

<Info>
  Production keys are read-only in the Developer Portal. Once a template behaves as expected on beta, request a production review from your Production key, and Para applies your active beta policies to production.
</Info>

<PermissionsCards basePath="/v3/react-native/guides/permissions" pages={["json", "testing", "production"]} cols={3} />


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