Miracle Docs

Get API Credentials

Step 1 of 4 — You need API keys to authenticate requests to the Miracle API. This page explains how to get them and how authentication works.


API key types

Every API key is a pair — a secret key and a publishable key, generated together. A third credential type, the client secret, is generated per checkout session. Each credential serves a different purpose:

CredentialFormatUseWhere
Secret keysk_test_... / sk_live_...Authenticates server-side API requests (payments, refunds, sessions)Your backend only
Publishable keypk_test_... / pk_live_...Identifies your account in client-side flows (tokenization, payment methods)Frontend JS, mobile apps
Client secretOpaque token (returned when creating a checkout session)Authenticates HPP/widget flows — scoped to a single checkout sessionHPP, payment widget

Test vs. live keys

Each key pair belongs to an environment:

EnvironmentKey prefixBehavior
Testsk_test_, pk_test_Sandbox only — no real money moves. Use these during development.
Livesk_live_, pk_live_Production — processes real payments. Use these only after you go live.

The environment is determined server-side from the key prefix. You do not need to pass an environment parameter in your requests.


Get your keys

  1. Log in to the Miracle Portal.
  2. Navigate to Settings > API Keys.
  3. Click Create API Key.
  4. Give the key a descriptive name (e.g., "Backend — staging" or "Mobile app").
  5. Copy both the publishable key and the secret key.

Your secret key is shown only once. Copy it immediately and store it somewhere secure. If you lose it, you will need to create a new key pair.

You can optionally restrict the key to a subset of permissions. If you leave permissions unrestricted, the key inherits the full scope of its owner.


Authentication

All API requests are authenticated with a Bearer token in the Authorization header. Use your secret key for server-side calls:

curl https://api.miracle.com/v1/payments \
  -H "Authorization: Bearer sk_test_your_secret_key" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.miracle.com/v1/payments', {
  headers: {
    'Authorization': `Bearer ${process.env.MIRACLE_SECRET_KEY}`,
    'Content-Type': 'application/json',
  },
});

const { data } = await response.json();
import os
import requests

response = requests.get(
    "https://api.miracle.com/v1/payments",
    headers={
        "Authorization": f"Bearer {os.environ['MIRACLE_SECRET_KEY']}",
        "Content-Type": "application/json",
    },
)

data = response.json()["data"]

When to use which credential

ScenarioCredential to use
Create a payment from your serversk_test_ / sk_live_
Create a refundsk_test_ / sk_live_
Create an HPP checkout sessionsk_test_ / sk_live_
Tokenize a card from your frontendpk_test_ / pk_live_
Fetch available payment methods from your frontendpk_test_ / pk_live_
Tokenize, fetch payment methods, or pay within HPP/widgetClient secret

Publishable keys only grant access to the /tokenize and /payment-methods endpoints. Client secrets additionally grant access to /payments, but only for the associated checkout session. Any other endpoint will return 403 Forbidden.

Origin restrictions for publishable keys. Live publishable keys (pk_live_*) validate the request origin against the allowed origins configured on your merchant account. Requests from unregistered origins are rejected with 403 Forbidden. Test publishable keys (pk_test_*) skip this check so you can develop freely from any origin, including localhost.

Idempotency

All write operations (POST, PATCH, DELETE) require an Idempotency-Key header. This lets you safely retry requests without creating duplicate side-effects (e.g., double-charging a customer).

Idempotency-Key: your-unique-request-id

Use a unique value per request — a UUID v4 works well. The API will return the same response for repeated calls with the same idempotency key.


Key lifecycle

API keys have three possible states:

StateDescription
ActiveKey is usable for API requests.
RevokedManually revoked. Immediate and irreversible.
ExpiredPast its expiration date (if one was set at creation).

To rotate a key: create a new key pair, update your application, verify it works, then revoke the old key. There is no automatic rotation.


Security best practices

Protect your secret keys. Compromised keys can be used to create payments, issue refunds, and access transaction data on your account.

  • Never expose secret keys in client-side code. Do not include sk_ keys in JavaScript bundles, mobile apps, or HTML. Use publishable keys (pk_) for client-side calls.
  • Store keys in environment variables, not in source code or version control.
  • Use test keys for development. Switch to live keys only when you are ready to process real payments.
  • Rotate keys immediately if you suspect they have been compromised. Create a new pair, deploy it, then revoke the old key.
  • Restrict permissions when a key does not need full API access. For example, a key used only for creating payments does not need refund permissions.

Next step

You have your API keys — now create your first payment.

Your First Payment -->

On this page