> ## 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.

# REST API

> Server-to-server wallet and signing over HTTP

export const DemoCallout = ({variant = "card", title = "Interactive Demo", description = "Try the live demo to explore authentication flows and customize your modal before integrating."}) => {
  if (variant === "subtle") {
    return <div className="not-prose my-4 px-4 py-3 rounded-xl border border-orange-200 bg-orange-50/50">
        <div className="flex items-center justify-between gap-4">
          <p className="text-sm text-gray-700 m-0">
            {description}
          </p>
          <a href="https://demo.getpara.com/" target="_blank" rel="noopener noreferrer" className="not-prose flex-shrink-0 inline-flex items-center gap-2 px-3 py-1.5 text-xs font-semibold text-orange-600 bg-white border border-orange-200 rounded-lg hover:bg-orange-50 transition-colors no-underline">
            Try Demo
            <svg width="12" height="12" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M40 472L472 40M472 40H83.2M472 40V428.8" stroke="currentColor" strokeWidth="66.6667" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </a>
        </div>
      </div>;
  }
  return <a href="https://demo.getpara.com/" target="_blank" rel="noopener noreferrer" className="not-prose block my-4 p-5 rounded-xl bg-gradient-to-r from-orange-600 via-pink-600 to-purple-600 hover:opacity-95 transition-opacity no-underline">
      <div className="flex items-center justify-between gap-4">
        <div>
          <h3 className="text-base font-semibold text-white m-0">{title}</h3>
          <p className="text-xs text-white/80 mt-1 m-0">{description}</p>
        </div>
        <div className="flex-shrink-0 w-8 h-8 rounded-full bg-white/20 flex items-center justify-center">
          <svg width="14" height="14" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M40 472L472 40M472 40H83.2M472 40V428.8" stroke="white" strokeWidth="66.6667" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </div>
      </div>
    </a>;
};

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

export const Card = ({imgUrl, title, description, href, horizontal = false, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  const handleClick = e => {
    e.preventDefault();
    if (newTab) {
      window.open(href, '_blank', 'noopener,noreferrer');
    } else {
      window.location.href = href;
    }
  };
  return <div className={`not-prose relative my-2 p-[1px] rounded-xl transition-all duration-300 ${isHovered ? 'bg-gradient-to-r from-[#FF4E00] to-[#874AE3]' : 'bg-gray-200'}`} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      <a href={href} onClick={handleClick} className={`not-prose flex ${horizontal ? 'flex-row' : 'flex-col'} font-normal h-full bg-white overflow-hidden w-full cursor-pointer rounded-[11px] no-underline`}>
        {imgUrl && <div className={`relative overflow-hidden flex-shrink-0 ${horizontal ? 'w-[30%] rounded-l-[11px]' : 'w-full'}`} onClick={e => e.stopPropagation()}>
            <img src={imgUrl} alt={title} className="w-full h-full object-cover pointer-events-none select-none" draggable="false" />
            <div className="absolute inset-0 pointer-events-none" />
          </div>}
        <div className={`flex-grow px-6 py-5 ${horizontal ? 'w-[70%]' : 'w-full'} flex flex-col ${horizontal && imgUrl ? 'justify-center' : 'justify-start'}`}>
          {title && <h2 className="font-semibold text-base text-gray-800 m-0">{title}</h2>}
          {description && <div className={`font-normal text-gray-500 re leading-6 ${horizontal || !imgUrl ? 'mt-0' : 'mt-1'}`}>
              <p className="m-0 text-xs">{description}</p>
            </div>}
        </div>
      </a>
    </div>;
};

Para's REST API provides a simple HTTP surface for creating wallets and signing from your backend. Use
`@getpara/rest-sdk` when you want typed TypeScript methods and signer adapters; use the raw HTTP API when you want
language-native `fetch` or cURL.

<a href="/openapi.yaml" download="para-rest-api.yaml" className="inline-flex items-center gap-2 px-4 py-2.5 my-2 text-sm font-medium text-zinc-700 dark:text-zinc-200 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-gradient-to-b from-white to-zinc-50 dark:from-zinc-800 dark:to-zinc-900 shadow-xs hover:shadow-sm hover:border-zinc-300 dark:hover:border-zinc-700 transition-all">
  <Icon icon="file-code" size={18} className="text-primary" />

  <span>Download OpenAPI Spec</span>
</a>

## Prerequisites

To use Para, you need an API key. This key authenticates your requests to Para services and is essential for
integration.

<Warning>
  Don't have an API key yet? Request access to the <Link label="Developer Portal" href="https://developer.getpara.com" /> to create API keys, manage billing, teams, and more.
</Warning>

<DemoCallout variant="subtle" />

<Warning>
  You can restrict Para REST to specific IPs by adding CIDR entries in the [Developer Portal](https://developer.getpara.com). Once you add them, requests from other IPs return `401 Unauthorized`.
</Warning>

<Danger>
  **Protect your API key.** REST API wallets are permanently scoped to the project that created them. If you lose access
  to your API key, you can rotate it safely — but deleting the project or creating a new one means losing wallet access.
  See [Setup → Authentication](/v2/rest/setup#authentication) for details.
</Danger>

## When to Use

* **Programmatic (pregen) wallets** — the recommended way to create wallets for users before they sign up, build agent wallets, or run server-side signing.
* **Any secp256k1 or ed25519 chain** — the `sign-raw` endpoint is chain-agnostic. Create an EVM wallet for secp256k1 signing (works with Bitcoin, etc.) or a Solana/Stellar wallet for ed25519 signing, then hash and serialize transactions on your side.
* Your backend needs wallets and you prefer REST semantics over share-backed SDK ceremonies.
* You already rely on secret-key auth + IP allowlists.
* You prefer cURL or language-native HTTP clients over SDKs.

## Wallet Claiming

When a user signs up through your app with the same identifier used to create the wallet (e.g., the same email), the wallet is automatically claimed and transferred to their account. No server-side action is needed. For details on the client-side flow, see the [Web Pregeneration guide](/v2/react/guides/pregen#claiming-a-pregenerated-wallet).

## Next Steps

<CardGroup cols={2}>
  <Card title="REST SDK" imgUrl="/images/v2/general-server.png" href="/v2/rest/sdk" description="Typed TypeScript client and server-side signer adapters" />

  <Card title="Setup" imgUrl="/images/v2/general-server.png" href="/v2/rest/setup" description="Authentication and error handling" />

  <Card title="Multi-Wallet Setup" imgUrl="/images/v2/general-server.png" href="/v2/rest/multi-wallet" description="Multiple wallets per user with CUSTOM_ID" />

  <Card title="Migrate from SDK Pregen" imgUrl="/images/v2/general-server.png" href="/v2/rest/migrate-from-sdk-pregen" description="Move existing SDK pregen wallets to the REST API" />

  <Card title="Raw HTTP Example" imgUrl="/images/v2/general-examples.png" href="https://github.com/getpara/examples-hub/tree/2.0.0/server/rest-with-node" description="Low-level Node.js fetch baseline" />
</CardGroup>
