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:

    1. 1Seller creates a product → gets an upload URL
    2. 2Buyer submits data to the upload URL
    3. 3Buyer is redirected to Stripe Checkout
    4. 4After payment → buyer receives a permanent retrieval link
    5. 5Anyone with the link can GET the data, 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-1576877075---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.

    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:

    url
    https://t-1576877075---datastore-tmna4v27tq-uc.a.run.app/products/{product_id}        ← buyer-facing form
    https://t-1576877075---datastore-tmna4v27tq-uc.a.run.app/api/products/{product_id}    ← programmatic API

    No-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

    POST/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_idrequired
    string (path)

    The product ID from your dashboard.

    bodyrequired
    text/plain

    Raw data to store. Max 1 MB. Any text format accepted (JSON, CSV, plain text, etc.).

    Response

    200
    text/plain

    The Stripe Checkout URL. Redirect the buyer to this URL to complete payment.

    400
    text/plain

    Bad request — missing or oversized data.

    404
    text/plain

    Product not found.

    503
    text/plain

    Seller Stripe account not yet configured.

    GET/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

    bash
    curl -X POST https://t-1576877075---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)

    javascript
    const payload = JSON.stringify({ type: "config", zones: [1, 2, 3] });
    
    const res = await fetch("https://t-1576877075---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 Stripe

    Python

    python
    import requests, json
    
    payload = json.dumps({"type": "config", "zones": [1, 2, 3]})
    
    res = requests.post(
        "https://t-1576877075---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

    php
    $payload = json_encode(["type" => "config", "zones" => [1, 2, 3]]);
    
    $ch = curl_init("https://t-1576877075---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 Stripe

    Data retrieval

    GET/{stored_value_id}

    After a successful Stripe payment, the buyer is redirected to https://t-1576877075---datastore-tmna4v27tq-uc.a.run.app/{stored_value_id}. This endpoint returns the stored data as plain text. The URL is permanent and publicly accessible — the ID is long and random, making it effectively secret until shared.

    200
    text/plain

    The stored data, exactly as it was submitted.

    404
    text/plain

    No data found for this ID.

    bash
    # Retrieve stored data — no auth required
    curl https://t-1576877075---datastore-tmna4v27tq-uc.a.run.app/YOUR_STORED_VALUE_ID
    
    # Returns the original payload:
    # {"type": "config", "zones": [1, 2, 3]}

    Note on security

    The retrieval URL is not authenticated — it's public by design. Security relies on the ID being a long random string (a Firestore document ID). 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
    Integration Guide · DataStore