Integration Guide
Learn how to use DataStore to charge for data uploads and share the results freely.
Overview
DataStore lets you create paid upload endpoints. When a buyer submits data to your product's URL, they're redirected to Stripe Checkout. After payment, they receive a permanent public link to retrieve their data — which they can share with anyone.
The flow:
- 1Seller creates a product → gets an upload URL
- 2Buyer submits data to the upload URL
- 3Buyer is redirected to Stripe Checkout
- 4After payment → buyer receives a short retrieval code (e.g. AB3X7F2C)
- 5Anyone with the code can GET the data at /{product_id}/{code}, forever
Quick start
Get from signup to your first paid upload in under five minutes.
1. Create an account and connect Stripe
Sign up at https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/auth. After signing in, the dashboard will prompt you to connect your Stripe account via Stripe Express. This is required to receive payouts.
2. Create a product
In the dashboard, click New product and enter a name, optional description, and price in USD. Each product gets a unique upload URL. You can also set a custom redirect URL — after payment the buyer will be sent to that URL with ?code=XXXX appended, so you can brand the post-payment experience yourself.
3. Share the upload URL
Copy the URL from the product card. Share it with buyers directly, or use the API for programmatic access. The URL looks like:
https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/products/{product_id} ← buyer-facing form
https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/api/products/{product_id} ← programmatic APINo-code form
Every product automatically has a built-in web form at /products/{product_id}. Buyers can paste their data directly into a textarea, click pay, and be redirected to Stripe — no technical knowledge required.
When to use the form:
- • Your buyers are non-technical (e.g. end customers)
- • You want a zero-setup user experience
- • You're selling access to configuration or template uploads
The form accepts any text-based data up to 1 MB — JSON, CSV, plain text, YAML, or any format you choose.
API reference
/api/products/{product_id}Submit data for a product. Returns a Stripe Checkout URL. The buyer is expected to complete payment at that URL to receive the retrieval link.
Request
product_idrequiredThe product ID from your dashboard.
bodyrequiredRaw data to store. Max 1 MB. Any text format accepted (JSON, CSV, plain text, etc.).
Response
200The Stripe Checkout URL. Redirect the buyer to this URL to complete payment.
400Bad request — missing or oversized data.
404Product not found.
503Seller Stripe account not yet configured.
/api/products/{product_id}?data={payload}Same as POST but for environments that only support GET (e.g., browser URL-based integrations). The data query parameter holds the payload. On success, responds with a 302 redirect to the Stripe Checkout URL.
Code examples
Using the POST endpoint from common HTTP clients.
cURL
curl -X POST https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/api/products/YOUR_PRODUCT_ID \
-H "Content-Type: text/plain" \
-d '{"type": "config", "zones": [1, 2, 3]}'
# Response (200): https://checkout.stripe.com/pay/cs_...JavaScript (fetch)
const payload = JSON.stringify({ type: "config", zones: [1, 2, 3] });
const res = await fetch("https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/api/products/YOUR_PRODUCT_ID", {
method: "POST",
headers: { "Content-Type": "text/plain" },
body: payload,
});
if (!res.ok) throw new Error(await res.text());
const checkoutUrl = await res.text();
window.location.href = checkoutUrl; // redirect buyer to StripePython
import requests, json
payload = json.dumps({"type": "config", "zones": [1, 2, 3]})
res = requests.post(
"https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/api/products/YOUR_PRODUCT_ID",
data=payload,
headers={"Content-Type": "text/plain"},
)
res.raise_for_status()
checkout_url = res.text
print("Redirect buyer to:", checkout_url)PHP
$payload = json_encode(["type" => "config", "zones" => [1, 2, 3]]);
$ch = curl_init("https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/api/products/YOUR_PRODUCT_ID");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: text/plain"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$checkoutUrl = curl_exec($ch);
curl_close($ch);
header("Location: " . $checkoutUrl); // redirect buyer to StripeData retrieval
/{product_id}/{code}After payment, the buyer lands on a success page showing their retrieval code — a short, human-readable string like AB3X7F2C. The retrieval URL is scoped to the product: https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/{product_id}/{code}. This means a code issued for one product will return 404 if used against a different product — your app can confirm the buyer genuinely went through your checkout, not someone else's.
200The stored data, exactly as it was submitted.
404No data found for this code.
# Retrieve stored data — no auth required
curl https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/YOUR_PRODUCT_ID/AB3X7F2C
# Returns the original payload:
# {"type": "config", "zones": [1, 2, 3]}
# Wrong product ID → 404, even with a valid code
curl https://t-1204118741---datastore-tmna4v27tq-uc.a.run.app/OTHER_PRODUCT_ID/AB3X7F2C
# 404 Not foundNote on security
The retrieval endpoint is not authenticated — it's public by design. The code is a short alphanumeric string derived from a SHA-256 hash, intended to be easy to copy and share. Do not store sensitive secrets in DataStore; it is designed for shareable configuration data, templates, and similar artifacts.
Ready to start?
Create an account, connect Stripe, and start charging for uploads in minutes.
Get started free