DOCUMENTATION_PORTAL

Developer Reference Manual

Introduction

CloudState is an ultra-lightweight, high-density persistent document store designed specifically for AI agent workflows (like Cursor, v0, Bolt, and custom LLM scripts).

Instead of managing complex schema migrations, setting up local PostgreSQL pools, or writing backend endpoints, CloudState lets you persist the state of your application as a single root JSON object. You read it with a GET and save it with a PUT.

SPEED
< 30ms Latency
PAYLOAD
5 MB JSON Object
ARCHITECTURE
ACID Compliant DB

Quickstart

Get your database online in less than 60 seconds:

01

Create your account

Sign in using the CONSOLE button. CloudState integrates with Clerk to secure your project control plane.

02

Initialize a new project

Choose a universally unique slug (e.g. my-cool-agent-state) and configure the access control policy (public or private).

03

Copy credentials

Grab your API key (secret) and start calling GET and PUT from your client application or system prompt.

GET: Read Current State

Retrieve your project's JSON state. If your project is marked as Private, you must provide the x-api-key in the request header. If the project is Public, the header is optional. The response includes an x-version header indicating the current internal document version.

HTTP Request

GET https://cloudstate.onrender.com/v1/db/:slug

Headers

HeaderValueDescription
x-api-keysk_live_...Required if project is Private.

cURL Example

TERMINAL (GET)
curl -X GET https://cloudstate.onrender.com/v1/db/my-project-slug \ -H "x-api-key: sk_live_deb2be3f9d8d9a5895c51016"

PUT: Replace Current State

Replace the entire root JSON object with a new payload. The payload must be a valid JSON object or array. PUT requests strictly require the project's x-api-key header.

HTTP Request

PUT https://cloudstate.onrender.com/v1/db/:slug

Headers

HeaderValueDescription
x-api-keysk_live_...Required for all projects.
x-versionstring (integer)Optional. Set to enforce optimistic concurrency control. Mismatches will return 409 Conflict.
Content-Typeapplication/jsonRequired.

cURL Example

TERMINAL (PUT)
curl -X PUT https://cloudstate.onrender.com/v1/db/my-project-slug \ -H "Content-Type: application/json" \ -H "x-version: 7" \ -H "x-api-key: sk_live_deb2be3f9d8d9a5895c51016" \ -d '{"status": "active", "temperature": 0.7}'

Optimistic Concurrency Control

To prevent concurrent updates from overwriting each other in multi-user applications (like collaborative tools, voting systems, or shared lists), CloudState implements optimistic version protection.

Each project maintains an internal document version integer starting at 1 which increments on every successful write.

How it works:

  1. Read the current version from the x-version response header on a GET request.
  2. Send that version back as the x-version request header on your subsequent PUT request.
  3. CloudState compares your submitted version with the database version. If they match, the update is accepted and the version increments.
  4. If the database has already been updated by another client, the version won't match, and CloudState returns an HTTP 409 Conflict error.

Conflict Response (409 Conflict)

JSON_RESPONSE (409 CONFLICT)
{ "error": "version_conflict", "message": "State changed since your last fetch. Fetch latest state and retry.", "currentVersion": 8 }

Recommended Retry Strategy

When your client receives a 409 Conflict, you should:

  • Perform a new GET request to pull the latest state and the new x-version.
  • Re-apply your local changes/mutation onto that fresh state data.
  • Retry the PUT request once with the new version value.

Health Status Endpoint

Verify the operational status, versioning, and latency configurations of the CloudState API gateway. This endpoint is public and does not require credentials.

HTTP Request

GET https://cloudstate.onrender.com/

cURL Example

TERMINAL (HEALTH)
curl -X GET https://cloudstate.onrender.com/

Response Template (200 OK)

JSON_RESPONSE
{ "status": "ok", "service": "CloudState API", "version": "1.1.0 (Clerk Auth)", "uptime": "98.9%" }

Simple Integration Snippets

Use these simple 5-line examples to quickly establish reads and writes inside your codebase.

JavaScript / Node.js Fetch

JS_GET.JS
// Simple GET Request (Read State with version) fetch('https://cloudstate.onrender.com/v1/db/my-project-slug', { headers: { 'x-api-key': 'sk_live_deb2be...' } }) .then(res => { const version = res.headers.get('x-version'); console.log('Document Version:', version); return res.json(); }) .then(data => console.log('Current State:', data));
JS_PUT.JS
// Simple PUT Request (Write State with version) fetch('https://cloudstate.onrender.com/v1/db/my-project-slug', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'x-version': '7', 'x-api-key': 'sk_live_deb2be...' }, body: JSON.stringify({ status: 'online', logs: [] }) }) .then(res => { if (res.status === 409) { console.error('Conflict detected! Fetch latest state and retry.'); } return res.json(); }) .then(result => console.log('Result:', result));

Python Requests

PY_GET.PY
# Simple GET Request (Read State with version) import requests url = "https://cloudstate.onrender.com/v1/db/my-project-slug" headers = {"x-api-key": "sk_live_deb2be..."} response = requests.get(url, headers=headers) version = response.headers.get("x-version") data = response.json() print(f"Version: {version} | State:", data)
PY_PUT.PY
# Simple PUT Request (Write State with version) import requests url = "https://cloudstate.onrender.com/v1/db/my-project-slug" headers = { "x-api-key": "sk_live_deb2be...", "x-version": "7", "Content-Type": "application/json" } payload = {"status": "online", "logs": []} response = requests.put(url, headers=headers, json=payload) if response.status_code == 409: print("Conflict! Fetch latest and retry:", response.json()) else: print("Saved:", response.json())

Production State Recipes

Since CloudState mutations replace the entire root JSON, we recommend using debounce logic in client views to throttle HTTP requests.

React Debounced Hook

USE_CLOUD_STATE.TS
import { useState, useEffect, useRef } from "react"; export function useCloudState<T>(endpoint: string, apiKey: string, initialData: T) { const [state, setState] = useState<T>(initialData); const [syncing, setSyncing] = useState(false); const [error, setError] = useState<string | null>(null); // Track document version returned by GET/PUT in a mutable ref const versionRef = useRef<number | null>(null); // 1. Fetch data and capture its x-version header async function loadData() { try { const res = await fetch(endpoint, { headers: { "x-api-key": apiKey } }); if (res.ok) { // Read x-version header const ver = res.headers.get("x-version"); if (ver) versionRef.current = parseInt(ver, 10); const data = await res.json(); setState(data); } } catch (err: any) { setError("Load error: " + err.message); } } useEffect(() => { loadData(); }, [endpoint, apiKey]); // 2. Write data with x-version protection and automatic single-retry const updateState = async (nextState: T) => { setSyncing(true); setError(null); // Optimistically update local view setState(nextState); try { const headers: Record<string, string> = { "Content-Type": "application/json", "x-api-key": apiKey }; if (versionRef.current !== null) { headers["x-version"] = versionRef.current.toString(); } const res = await fetch(endpoint, { method: "PUT", headers, body: JSON.stringify(nextState) }); if (res.status === 409) { // Version conflict! Re-fetch latest state and retry once const freshRes = await fetch(endpoint, { headers: { "x-api-key": apiKey } }); if (!freshRes.ok) throw new Error("Failed to re-fetch state during conflict resolution"); const freshVer = freshRes.headers.get("x-version"); if (freshVer) versionRef.current = parseInt(freshVer, 10); const freshData = await freshRes.json(); // Merge strategy: applying the update block to the fresh data const mergedState = { ...freshData, ...nextState }; setState(mergedState); const retryRes = await fetch(endpoint, { method: "PUT", headers: { "Content-Type": "application/json", "x-api-key": apiKey, "x-version": versionRef.current?.toString() || "" }, body: JSON.stringify(mergedState) }); if (!retryRes.ok) throw new Error("Retry after conflict failed"); const finalVer = retryRes.headers.get("x-version"); if (finalVer) versionRef.current = parseInt(finalVer, 10); } else if (!res.ok) { throw new Error("Save failed: " + res.statusText); } else { const finalVer = res.headers.get("x-version"); if (finalVer) versionRef.current = parseInt(finalVer, 10); } } catch (err: any) { setError(err.message); } finally { setSyncing(false); } }; return { state, updateState, syncing, error, reload: loadData }; }

Python Class Adapter

CLIENT.PY
import requests class CloudStateClient: def __init__(self, slug: str, api_key: str): self.url = f"https://cloudstate.onrender.com/v1/db/{slug}" self.headers = { "x-api-key": api_key, "Content-Type": "application/json" } def get_state(self): """Retrieve current JSON root state.""" res = requests.get(self.url, headers=self.headers) res.raise_for_status() return res.json() def save_state(self, payload: dict): """Replace root JSON state.""" res = requests.put(self.url, headers=self.headers, json=payload) res.raise_for_status() return res.json()

AI Agent System Prompts

PROJECT_SPECIFIC_AI_PROMPTS

Instead of copying generic guidelines, you can get a system prompt tailored with your project's unique database slug, access token, and access controls. Navigate to your Project Dashboard in the console and click the **COPY_FULL_SYSTEM_PROMPT** button under the AI Prompt Engineering card. You can drop this directly into your `.cursorrules`, Bolt instructions, or v0 prompt files.

System Limits & Constraints

To maintain high speeds and prevent resource exhaustion, the following thresholds are applied across the standard platform tier:

MetricConstraintType
Max Projects5 ProjectsHard limit per account
Payload Limit5.0 MBPer project root JSON
Rate Limiting60 requests / minutePer IP / API Key
Database BackingPostgreSQL JSONBNeon Serverless DB