DCfnDOCS

GETTING STARTED

DECENTRACLOUD is the only serverless compute platform that accepts USDC payments, runs on decentralized GPUs, and can't be censored.

USDC Payments

Pay per request with USDC on Solana. No credit card, no KYC, no bank account.

GPU Native

Functions run on decentralized GPU nodes. Built for AI inference and heavy compute.

Censorship Resistant

No single entity can shut down your functions. Truly decentralized infrastructure.

On-Chain Verifiable

Every execution produces on-chain verifiable logs. Transparent and auditable.

HOW IT WORKS

1. Get credits (faucet or USDC deposit)
2. POST /invoke with X-WALLET header + your code
3. Gateway deducts 1 credit (~1ms, no blockchain)
4. Job queued in Redis → Worker on Nosana GPU picks it up
5. Code runs in isolated Deno sandbox (no network, 128MB limit)
6. Result returned via GET /jobs/:id

QUICK START

1

GET FREE CREDITS

Claim free testnet credits — no USDC needed. For production, deposit USDC on-chain.

FAUCET
JavaScript
// Use your gateway URL (same as your domain in production)
const API = window.location.origin;
const WALLET = "YourSolanaWalletPublicKey";

// Get 50 free credits for testing (one-time only)
const res = await fetch(API + "/credits/faucet", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ wallet: WALLET }),
});
const credits = await res.json();
// { wallet: "YourWallet...", balance: 1000, estimatedRequests: 1000 }
2

DEPLOY A FUNCTION

Save your code as a named function. Deploy once, call anytime.

DEPLOY
JavaScript
const deploy = await fetch(API + "/functions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-WALLET": WALLET,
  },
  body: JSON.stringify({
    name: "hello-world",
    code: `function handler(payload) {
      return { greeting: "Hello, " + payload.name + "!", timestamp: Date.now() };
    }`,
  }),
});
const fn = await deploy.json();
// { name: "hello-world", endpoint: "/functions/hello-world/run" }
3

RUN YOUR FUNCTION

Call your function by name with any payload. Costs 1 credit per run.

RUN
JavaScript
const run = await fetch(API + "/functions/hello-world/run", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-WALLET": WALLET,
  },
  body: JSON.stringify({ payload: { name: "Sebastian" } }),
});
const { jobId } = await run.json();
// { jobId: "abc-123...", status: "queued", pollUrl: "/jobs/abc-123..." }
4

GET THE RESULT

Poll the job endpoint until status is "done", "error", or "timeout".

POLL RESULT
JavaScript
// Poll every 1 second until done
let result;
while (true) {
  const res = await fetch(API + "/jobs/" + jobId);
  result = await res.json();
  if (["done", "error", "timeout"].includes(result.status)) break;
  await new Promise(r => setTimeout(r, 1000));
}

console.log(result);
// {
//   jobId: "abc-123...",
//   status: "done",
//   result: '{"greeting":"Hello, Sebastian!","timestamp":1713564000}',
//   durationMs: 47
// }

API REFERENCE

Base URL: your-domain.com (same origin as your deployment)

POST/credits/deposit

Deposit USDC credits. Verifies the on-chain transaction and adds credits to your balance. This is the only step that touches the blockchain.

REQUEST BODY
JSON
{
  "txSignature": "5xG7...your_solana_tx_signature"
}
RESPONSE
JSON
{
  "wallet": "YourWa11etAddress...",
  "creditsAdded": 1000,
  "totalBalance": 1500,
  "txSignature": "5xG7..."
}
GET/credits/balance/:wallet

Check your current credit balance and estimated remaining requests.

RESPONSE
JSON
{
  "wallet": "YourWa11etAddress...",
  "balance": 1500,
  "estimatedRequests": 1500
}
POST/credits/faucet

Claim 50 free credits for testing. One-time only per wallet. No on-chain transaction needed.

REQUEST BODY
JSON
{
  "wallet": "YourWa11etAddress..."
}
RESPONSE
JSON
{
  "wallet": "YourWa11etAddress...",
  "balance": 50,
  "estimatedRequests": 50
}
POST/invoke

Execute a serverless function. Costs 1 credit per request. No on-chain transaction needed — deducts from pre-paid balance instantly.

HEADERS
X-WALLET: YourWa11etAddress...
REQUEST BODY
JSON
{
  "code": "function handler(payload) { return payload.x * 2; }",
  "payload": { "x": 21 },
  "timeoutMs": 30000,
  "webhookUrl": "https://your-app.com/webhook"
}
RESPONSE
JSON
{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued",
  "pollUrl": "/jobs/550e8400-e29b-41d4-a716-446655440000"
}
GET/jobs/:id

Get the status and result of a job. Poll this endpoint until status is 'done', 'error', or 'timeout'.

RESPONSE
JSON
{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "done",
  "result": "{\"value\":42}",
  "durationMs": 234
}
GET/jobs?wallet=...&limit=20&offset=0

List all jobs for a given wallet address, sorted by creation date (newest first).

RESPONSE
JSON
[
  {
    "id": "550e8400-...",
    "status": "done",
    "createdAt": "2025-04-19T...",
    "durationMs": 234
  }
]
POST/functions

Deploy or update a named function. The code is saved permanently and can be executed anytime by name.

HEADERS
X-WALLET: YourWa11etAddress...
REQUEST BODY
JSON
{
  "name": "my-function",
  "code": "function handler(payload) { return { result: payload.x * 2 }; }"
}
RESPONSE
JSON
{
  "name": "my-function",
  "wallet": "YourWa11etAddress...",
  "createdAt": "2026-04-21T...",
  "endpoint": "/functions/my-function/run"
}
GET/functions

List all your deployed functions. Returns function metadata without code.

HEADERS
X-WALLET: YourWa11etAddress...
RESPONSE
JSON
[
  {
    "name": "my-function",
    "executions": 42,
    "updatedAt": "2026-04-21T...",
    "createdAt": "2026-04-21T..."
  }
]
POST/functions/:name/run

Execute a deployed function by name. Costs 1 credit. Returns a job ID for polling.

HEADERS
X-WALLET: YourWa11etAddress...
REQUEST BODY
JSON
{
  "payload": { "x": 21 }
}
RESPONSE
JSON
{
  "jobId": "550e8400-...",
  "status": "queued",
  "pollUrl": "/jobs/550e8400-..."
}
DELETE/functions/:name

Delete a deployed function permanently.

HEADERS
X-WALLET: YourWa11etAddress...
RESPONSE
JSON
{
  "deleted": true,
  "name": "my-function"
}
GET/health

Check the health status of the gateway, queue, and worker nodes.

RESPONSE
JSON
{
  "status": "ok",
  "queueLength": 3,
  "activeWorkers": 3,
  "redisOk": true,
  "timestamp": "2025-04-19T..."
}

CODE EXAMPLES

All examples use plain fetch() — no SDK needed. Works in any language or environment.

Full flow: faucet → deploy → run → result

Complete example from zero to running a function.

EXAMPLE
// Use your gateway URL (same as your domain in production)
const API = window.location.origin;
const WALLET = "YourSolanaWalletPublicKey";

// 1. Get free credits
await fetch(API + "/credits/faucet", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ wallet: WALLET }),
});

// 2. Deploy a function
await fetch(API + "/functions", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-WALLET": WALLET },
  body: JSON.stringify({
    name: "calculator",
    code: `function handler(p) { return { result: eval(p.expression) }; }`,
  }),
});

// 3. Run it
const { jobId } = await (await fetch(API + "/functions/calculator/run", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-WALLET": WALLET },
  body: JSON.stringify({ payload: { expression: "2 ** 10" } }),
})).json();

// 4. Get result
await new Promise(r => setTimeout(r, 2000));
const result = await (await fetch(API + "/jobs/" + jobId)).json();
console.log(result); // { status: "done", result: '{"result":1024}' }

One-off execution (no deploy needed)

Run code directly without saving it as a function.

EXAMPLE
const { jobId } = await (await fetch(API + "/invoke", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-WALLET": WALLET },
  body: JSON.stringify({
    code: `function handler(payload) {
      const { numbers } = payload;
      return {
        sum: numbers.reduce((a, b) => a + b, 0),
        avg: numbers.reduce((a, b) => a + b, 0) / numbers.length,
      };
    }`,
    payload: { numbers: [10, 20, 30, 40, 50] },
    timeoutMs: 30000,
  }),
})).json();

cURL examples

Use from any terminal or backend.

EXAMPLE
# Get credits
curl -X POST https://your-domain.com/credits/faucet \
  -H "Content-Type: application/json" \
  -d '{"wallet": "YourWallet..."}'

# Deploy function
curl -X POST https://your-domain.com/functions \
  -H "Content-Type: application/json" \
  -H "X-WALLET: YourWallet..." \
  -d '{"name":"hello","code":"function handler(p) { return { hi: p.name }; }"}'

# Run function
curl -X POST https://your-domain.com/functions/hello/run \
  -H "Content-Type: application/json" \
  -H "X-WALLET: YourWallet..." \
  -d '{"payload":{"name":"World"}}'

# Check result
curl https://your-domain.com/jobs/YOUR_JOB_ID

Python example

Works with any HTTP client in any language.

EXAMPLE
import requests

API = "https://your-domain.com"  # Your gateway URL
WALLET = "YourWallet..."

# Run a function
res = requests.post(f"{API}/functions/hello/run",
    headers={"Content-Type": "application/json", "X-WALLET": WALLET},
    json={"payload": {"name": "Python"}}
)
job_id = res.json()["jobId"]

# Poll for result
import time
while True:
    result = requests.get(f"{API}/jobs/{job_id}").json()
    if result["status"] in ["done", "error", "timeout"]:
        break
    time.sleep(1)

print(result)

🔑 AUTHENTICATION

DC fn supports two authentication methods. API Keys are recommended for production — they're permanent, secure, and don't require signing each request.

API KEY (PRODUCTION)

Permanent token generated by signing a message with your wallet. Use in any HTTP client.

HEADER
Authorization: Bearer dc_a3f8b2c1d9e7...

X-WALLET (TESTING ONLY)

Pass your wallet address directly. Only for playground and local testing — not secure for production.

HEADER
X-WALLET: YourWa11etAddress...

GENERATING AN API KEY

Connect your Solana wallet, sign a verification message, and receive a permanent API key. The key is tied to your wallet and can be revoked anytime.

GENERATE API KEY
JavaScript
// 1. Sign a message with your wallet (browser)
const message = "DecentraCloud API Key Generation\n" +
  "Wallet: " + wallet.publicKey + "\n" +
  "Timestamp: " + Date.now();

const signature = await wallet.signMessage(
  new TextEncoder().encode(message)
);

// 2. Send to the API
const res = await fetch(API + "/auth/generate-key", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    wallet: wallet.publicKey.toString(),
    signature: btoa(String.fromCharCode(...signature)),
    message,
  }),
});

const { apiKey } = await res.json();
// apiKey: "dc_a3f8b2c1d9e7..." — save this securely!

USING YOUR API KEY

EVERY REQUEST
JavaScript
// Use your API key in the Authorization header
const res = await fetch(API + "/functions/my-function/run", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer dc_a3f8b2c1d9e7..."
  },
  body: JSON.stringify({ payload: { name: "World" } }),
});
CURL
curl -X POST https://your-domain.com/functions/my-function/run \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer dc_a3f8b2c1d9e7..." \
  -d '{"payload":{"name":"World"}}'
PYTHON
Python
import requests

res = requests.post(
    "https://your-domain.com/functions/my-function/run",
    headers={
        "Authorization": "Bearer dc_a3f8b2c1d9e7...",
        "Content-Type": "application/json",
    },
    json={"payload": {"name": "World"}}
)

API KEY ENDPOINTS

POST/auth/generate-key

Generate a permanent API key. Requires wallet signature to prove ownership. Replaces any existing key for this wallet.

REQUEST BODY
JSON
{
  "wallet": "YourSolanaPublicKey...",
  "signature": "base64EncodedSignature...",
  "message": "DecentraCloud API Key Generation..."
}
RESPONSE
JSON
{
  "apiKey": "dc_a3f8b2c1d9e7f4a5b6c8d0e1f2...",
  "wallet": "YourSolanaPublicKey...",
  "message": "Store this API key securely."
}
GET/auth/key-info/:wallet

Get information about your API key without revealing the full key.

RESPONSE
JSON
{
  "hasKey": true,
  "keyPreview": "dc_a3f8...d9e7",
  "createdAt": "2026-04-21T...",
  "lastUsedAt": "2026-04-21T...",
  "requestCount": 142
}
DELETE/auth/revoke-key/:wallet

Permanently revoke your API key. Any code using it will immediately stop working. Generate a new one afterward.

RESPONSE
JSON
{
  "revoked": true,
  "wallet": "YourSolanaPublicKey..."
}

CREDITS & BILLING

DECENTRACLOUD uses a pre-paid credit system. You deposit USDC once (on-chain), and each function execution deducts from your balance instantly (off-chain, ~1ms).

PRICING

$0.000010per request
USDC DepositedCreditsRequests
$0.0011,0001,000
$0.0110,00010,000
$0.10100,000100,000
$1.001,000,0001,000,000
$10.0010,000,00010,000,000

HOW IT WORKS

  1. Deposit once — Send USDC to the platform wallet on Solana, then call POST /credits/deposit with the TX signature.
  2. Credits added instantly — Your balance is updated in Redis. No more on-chain transactions needed.
  3. Each /invoke costs 1 credit — Deducted atomically from your balance (~1ms, no blockchain latency).
  4. Balance hits 0? — You get a 402 response. Deposit more USDC to continue.

SANDBOX LIMITS

All functions execute in an isolated Deno sandbox with these restrictions:

LimitValue
Max code size1 MB
Max payload size10 KB
Default timeout30 seconds
Max timeout120 seconds
Memory limit128 MB
Network accessDisabled
File system writeDisabled
File system read/tmp only
External importsDisabled
Rate limit100 req/min per wallet

WRITING YOUR FUNCTION

  • • The payload object is available as a global variable
  • • Export a handler(payload) function that returns your result
  • • The return value is serialized as JSON and returned in the job result
  • • Use console.log() for debugging (captured in logs)
  • • Top-level await is supported
EXAMPLE FUNCTION
TypeScript
function handler(payload) {
  // payload is the JSON object you sent with your request
  const { numbers } = payload;

  const sum = numbers.reduce((a, b) => a + b, 0);
  const avg = sum / numbers.length;

  return {
    sum,
    average: avg,
    count: numbers.length,
    max: Math.max(...numbers),
    min: Math.min(...numbers),
  };
}

// Invoke with: { "numbers": [10, 20, 30, 40, 50] }