Skip to main content
POST
/
guest-wallets
Create guest wallet
curl --request POST \
  --url https://xquik.com/api/v1/guest-wallets \
  --header 'Content-Type: <content-type>' \
  --header 'Idempotency-Key: <idempotency-key>' \
  --header 'x-api-key: <api-key>' \
  --data '
{
  "amount_minor": 123,
  "currency": "<string>"
}
'
import requests

url = "https://xquik.com/api/v1/guest-wallets"

payload = {
"amount_minor": 123,
"currency": "<string>"
}
headers = {
"Content-Type": "<content-type>",
"Idempotency-Key": "<idempotency-key>",
"x-api-key": "<api-key>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {
'Content-Type': '<content-type>',
'Idempotency-Key': '<idempotency-key>',
'x-api-key': '<api-key>'
},
body: JSON.stringify({amount_minor: 123, currency: '<string>'})
};

fetch('https://xquik.com/api/v1/guest-wallets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://xquik.com/api/v1/guest-wallets"

payload := strings.NewReader("{\n \"amount_minor\": 123,\n \"currency\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "<content-type>")
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("x-api-key", "<api-key>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
{
  "account_required": true,
  "amount": {},
  "checkout_url": "<string>",
  "api_key": "<string>",
  "authorization": {},
  "credential_notice": "<string>",
  "status_url": "<string>",
  "poll_after_seconds": 123,
  "requires_user_interaction": true,
  "instructions": "<string>",
  "purchase_id": "<string>",
  "status": "<string>",
  "expires_at": "<string>",
  "credits": "<string>",
  "wallet_id": "<string>"
}
Create a prepaid read wallet without an account, email address, or dashboard. This endpoint creates a one-use Stripe-hosted Payment Link after the user confirms a USD amount. It does not charge the user.
Ask the user to confirm the amount before calling this endpoint. Give the returned checkout_url to the user. Never open, submit, or complete the payment for them.
idempotency_key=$(uuidgen | tr '[:upper:]' '[:lower:]')
response=$(curl -sS -X POST https://xquik.com/api/v1/guest-wallets \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $idempotency_key" \
  -d '{"amount_minor": 1000, "currency": "usd"}')
api_key=$(jq -r '.api_key' <<<"$response")
checkout_url=$(jq -r '.checkout_url' <<<"$response")
wallet_id=$(jq -r '.wallet_id' <<<"$response")
# Store $api_key and $idempotency_key in your secret manager. Do not print them.
printf 'Created guest wallet %s. Open %s\n' "$wallet_id" "$checkout_url"
import { randomUUID } from "node:crypto";

const idempotencyKey = randomUUID();
const response = await fetch("https://xquik.com/api/v1/guest-wallets", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": idempotencyKey,
  },
  body: JSON.stringify({ amount_minor: 1000, currency: "usd" }),
});
const wallet = await response.json();
const apiKey = wallet.api_key;
// Store apiKey and idempotencyKey in your secret manager. Do not print them.
process.stdout.write(String(wallet.checkout_url) + "\n");
Store both api_key and the original Idempotency-Key as secrets. An exact replay can return the same response, including the key. No email recovery is available. Give only checkout_url to the user. After payment, poll status_url every poll_after_seconds with the guest key. Stop when latest_purchase.status is no longer pending. Do not call paid reads until usable is true.

Headers

Content-Type
string
required
Must be application/json.
Idempotency-Key
string
required
A cryptographically random UUID v4. Reuse it only for an exact retry of the same amount. Store it as a secret because it can recover the initial key.

Body

amount_minor
integer
required
Confirmed USD amount in cents. Minimum 1000 and maximum 25000.
currency
string
required
Must be usd.

Response

account_required
boolean
Always false.
amount
object
Confirmed amount in minor units and usd currency.
checkout_url
string
One-use Stripe-hosted Payment Link for the user to open.
api_key
string
Guest key returned on initial creation and exact idempotent replay. Store it as a secret.
authorization
object
Required Bearer header and scheme.
credential_notice
string
One-time credential storage guidance.
status_url
string
API URL to poll with the guest key.
poll_after_seconds
integer
Minimum polling delay. Always 2 for a pending purchase.
requires_user_interaction
boolean
Always true.
instructions
string
Required user interaction and polling guidance.
purchase_id
string
Guest purchase ID.
status
string
Initial purchase status. Normally pending.
expires_at
string
Pending Payment Link expiry. New links expire after 60 minutes.
credits
string
Credits to grant after verified payment.
wallet_id
string
Guest wallet ID.
{
  "account_required": false,
  "amount": { "amount_minor": 1000, "currency": "usd" },
  "api_key": "xq_example_returned_once",
  "authorization": { "header": "Authorization", "scheme": "Bearer" },
  "checkout_url": "https://buy.stripe.com/example",
  "credential_notice": "Store api_key and the Idempotency-Key securely before sharing checkout_url. No email recovery is available.",
  "credits": "66666",
  "expires_at": "2026-07-13T13:00:00.000Z",
  "instructions": "Give checkout_url to the user. They must complete payment on Stripe. Never submit payment for them. After payment, poll status_url every poll_after_seconds until latest_purchase.status is no longer pending.",
  "poll_after_seconds": 2,
  "purchase_id": "gp_example",
  "requires_user_interaction": true,
  "status": "pending",
  "status_url": "https://xquik.com/api/v1/guest-wallets/status",
  "wallet_id": "gw_example"
}
The response sends Cache-Control: no-store, private. An exact replay also sends Idempotent-Replayed: true.
Last modified on July 13, 2026