Skip to content
Viresso. Documentation Open Viresso

Code Examples

On this page

Use an API key from Settings → API Keys. Replace {workspace} with your workspace name and {api_key} with the key shown when you create it.

Laravel

use Illuminate\Support\Facades\Http;

$response = Http::withToken('{api_key}')
    ->acceptJson()
    ->get('https://app.example.com/api/v1/{workspace}/entries', [
        'contentBucket' => 'content',
        'contentType' => 'pages',
    ]);

$entries = $response->throw()->json();

PHP

$url = 'https://app.example.com/api/v1/{workspace}/entries?contentBucket=content&contentType=pages';

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Authorization: Bearer {api_key}',
    ],
]);

$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($status >= 400) {
    throw new RuntimeException($body);
}

$entries = json_decode($body, true, flags: JSON_THROW_ON_ERROR);

Node.js

const url = new URL("https://app.example.com/api/v1/{workspace}/entries");
url.searchParams.set("contentBucket", "content");
url.searchParams.set("contentType", "pages");

const response = await fetch(url, {
  headers: {
    Accept: "application/json",
    Authorization: "Bearer {api_key}",
  },
});

if (!response.ok) {
  throw new Error(await response.text());
}

const entries = await response.json();

Create an entry

const response = await fetch("https://app.example.com/api/v1/{workspace}/entries?contentBucket=content&contentType=pages", {
  method: "POST",
  headers: {
    Accept: "application/json",
    Authorization: "Bearer {api_key}",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    status: "published",
    fields: {
      title: "About",
      slug: "about",
    },
  }),
});

const entry = await response.json();

Upload a file

Uploads require the files:write ability and the key creator's permission to create workspace files. Send one file per request. The response is the file object directly, with an integer id, metadata, permanent download_url, and a temporary_url valid for 10 minutes. temporary_url_expires_at gives its expiry. Use GET /api/v1/{workspace}/files/{id} with files:read to obtain a fresh temporary link.

curl

curl "https://app.example.com/api/v1/acme/files" \
  -H "Authorization: Bearer $VIRESSO_API_KEY" \
  -H "Accept: application/json" \
  -F "file=@./photo.png"

Laravel upload

use Illuminate\Support\Facades\Http;

$stream = fopen(storage_path('app/photo.png'), 'rb');

try {
    $file = Http::withToken('{api_key}')
        ->acceptJson()
        ->attach('file', $stream, 'photo.png')
        ->post('https://app.example.com/api/v1/{workspace}/files')
        ->throw()
        ->json();
} finally {
    if (is_resource($stream)) {
        fclose($stream);
    }
}

$fileId = $file['id'];

Node.js upload and attachment

This server-side example uses Node.js 20+ native fetch, FormData, and openAsBlob. The key needs both files:write and entries:write. It assumes the pages content type has title, slug, and a single attachment field named hero_image.

import { openAsBlob } from "node:fs";

const baseUrl = "https://app.example.com/api/v1/acme";
const headers = {
  Accept: "application/json",
  Authorization: `Bearer ${process.env.VIRESSO_API_KEY}`,
};

const body = new FormData();
body.set("file", await openAsBlob("./photo.png"), "photo.png");

const upload = await fetch(`${baseUrl}/files`, {
  method: "POST",
  headers,
  body,
});
if (!upload.ok) throw new Error(await upload.text());
const file = await upload.json();

const create = await fetch(`${baseUrl}/entries?contentBucket=content&contentType=pages`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    status: "draft",
    fields: {
      title: "About",
      slug: "about",
      hero_image: file.id,
    },
  }),
});
if (!create.ok) throw new Error(await create.text());
const entry = await create.json();

Let the HTTP client set the multipart boundary; do not add a JSON Content-Type to the upload request. Upload and entry creation are separate requests: if entry validation fails, the file remains available in the workspace library.

See Files API for permitted types, size limits, base64 uploads, and downloads.

Delete a file

Deletion requires files:delete and the key creator's permission to delete workspace files. Use the integer file ID returned by an upload or an entry attachment. The file is also removed from attachment fields in the workspace's entries.

curl -X DELETE "https://app.example.com/api/v1/acme/files/18" \
  -H "Authorization: Bearer $VIRESSO_API_KEY" \
  -H "Accept: application/json"

For a server-side Node.js client:

const response = await fetch("https://app.example.com/api/v1/acme/files/18", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.VIRESSO_API_KEY}`,
    Accept: "application/json",
  },
});

if (response.status !== 204) {
  throw new Error(`File deletion failed (${response.status}): ${await response.text()}`);
}
// Success has no body. Do not call response.json().

An already deleted or unavailable file returns 404. See Files API for permissions, rate limits, and storage behavior.

Hosted auth tokens

Hosted auth access tokens are only for app user authentication through the hosted auth endpoints. They are not API keys. Use an API key for entry requests, file uploads and deletions, and email API requests. Tokenized file downloads use the returned URL without an API key.