Skip to main content

Overview

V01T is a flexible Business Intelligence platform designed to serve dynamic content via REST APIs. This guide walks you through:
  • Registering applications and data sources
  • Creating component data (nodes, artefacts, etc.)
  • Consuming the public API from your frontend
  • Handling fallback scenarios

Core Concepts

Applications

An Application is a logical container for your content. It represents a domain of data you want to publish (e.g., “devarno-ecosystem” for organization metadata, “flight-path” for blog articles). Applications belong to a Vault, which belongs to a User. Each application can have one or more Data Sources.

Data Sources

A Data Source links an application to a data connection (Notion, Airtable, JSON, etc.) and specifies which component types it manages.

Components

Components are the building blocks of your data:
  • node — organizational/structural data (e.g., ecosystem organizations)
  • artefact — content pieces (e.g., blog articles)
  • keyword, tag, feature — metadata and tagging
  • And others (status, narrative, entry, cluster, tier, gateway, format)

Quick Start: Register an Application

1. Create a User and Vault

from django.contrib.auth.models import User
from core.models import V01tUserSubscription, V01tDataVault

# Get or create user
user = User.objects.create_user(
    username='founder',
    email='founder@example.com'
)

# Create subscription
V01tUserSubscription.objects.create(
    user=user,
    tier='enterprise',
    is_active=True
)

# Create vault
vault = V01tDataVault.objects.create(
    user=user,
    slug='my-vault',
    name='My Data Vault',
    analytics_enabled=True,
    api_access_enabled=True,
    is_active=True
)

2. Create an Application

from core.models import V01tApplication, V01tApplicationTemplate

# Get or create template
template, _ = V01tApplicationTemplate.objects.get_or_create(
    code='my_app_type',
    defaults={
        'name': 'My App Type',
        'category': 'custom',
        'required_components': ['node'],
    }
)

# Create application
app = V01tApplication.objects.create(
    vault=vault,
    template=template,
    slug='my-application',
    name='My Application',
    status='active',
    is_active=True
)

3. Create a Data Source

from core.models import V01tApplicationDataSource, V01tDataResource, V01tPlatform

# Get or create platform
platform, _ = V01tPlatform.objects.get_or_create(
    name='Notion',
    defaults={
        'platform_type': 'notion',
        'api_base_url': 'https://api.notion.com',
    }
)

# Create data resource
resource = V01tDataResource.objects.create(
    owner=user,
    platform=platform,
    external_id='my-resource',
    name='My Data Source',
    is_validated=True,
    is_active=True
)

# Create data source linking app to resource
data_source = V01tApplicationDataSource.objects.create(
    application=app,
    data_resource=resource,
    component_type='node',
    source_alias='my-nodes',
    is_primary=True,
    sync_enabled=True
)

4. Create Component Data

from core.models import NodeData

# Create a node
node = NodeData.objects.create(
    data_source=data_source,
    title='Example Organization',
    slug='example-org',
    cluster='my-cluster',
    raw_data={
        'description': 'This is an example organization',
        'website': 'https://example.com',
        'repos': ['repo1', 'repo2'],
    },
    is_active=True
)

Consuming the API from Frontend

Use the @v01t/client TypeScript package (available in the workspace):
import { createV01tClient } from '@v01t/client';

const client = createV01tClient({
  baseUrl: 'https://api.v01t.io', // or your instance URL
});

// Fetch all nodes for an application
const response = await client.getNodes('my-application', {
  page_size: 50,
});

console.log(response.data); // Array of nodes
console.log(response.metadata.total_count); // Total count

API Patterns

Pagination

All list endpoints support pagination:
const response = await client.getNodes('my-application', {
  page: 1,
  page_size: 20,
});

// Response includes:
// - data: Component[],
// - metadata.total_pages: number,
// - metadata.has_next: boolean,
// - metadata.has_previous: boolean

Filtering

Components support various filters based on their fields:
// Filter by status
await client.getArtefacts('my-application', {
  status: 'published',
});

// Filter by priority
await client.getArtefacts('my-application', {
  min_priority: 1,
  max_priority: 3,
});

// Search
await client.getComponentData('my-application', 'node', {
  search: 'example',
});

Hydration

Enable hydration to include related data:
await client.getNodes('my-application', {
  hydrate: true,
});

Handling Fallback Data

If the V01T API is unavailable, serve static fallback data:
async function loadData() {
  try {
    const response = await client.getNodes('my-application');
    return response.data;
  } catch (error) {
    console.warn('V01T API unavailable, using fallback');
    return FALLBACK_DATA;
  }
}

Error Handling

The @v01t/client package exports error types for structured error handling:
import { V01tApiError, V01tNetworkError } from '@v01t/client';

try {
  const data = await client.getNodes('my-application');
} catch (error) {
  if (error instanceof V01tApiError) {
    console.error(`API Error ${error.status}: ${error.message}`);
  } else if (error instanceof V01tNetworkError) {
    console.error(`Network Error: ${error.message}`);
  }
}

Management Commands

V01T provides management commands for seeding and syncing data. See the Commands Guide for details.