Skip to content

API Basics

Welcome to String Theory! This guide will walk you through the fundamental concepts and help you make your first API calls. By the end, you’ll understand how String Theory works and be able to evaluate if it’s the right fit for your business.

In this guide, you’ll:

  • Understand the core concepts of String Theory
  • Set up a demo environment
  • Make your first deposit and withdrawal
  • Learn how money flows through the system
  • Explore key features like groups, tags, and threads
  • Basic understanding of APIs and JSON
  • A demo environment (we’ll help you set this up)
  • Bruno - Our recommended API testing tool (free and easy to use)

Before we dive in, let’s understand the key ideas that make String Theory different:

Knots are immutable units of money. Once created, they can’t be deleted or changed in any way. Any time we want to represent a change (such as a withdrawal), we create a new knot and mark the old one as “stale”. This ensures complete auditability.

String Theory uses whole numbers with predefined precision. For USD, we recommend currency_micros (6 decimal places), so $1.00 = 1,000,000 units.

Each piece of money belongs to exactly one owner, which helps with data distribution and privacy. Groups, Threads, and Holds are also associated with a single owner.

Money can be in multiple groups simultaneously (unlike traditional double-entry accounting).

Threads follow money as it moves through your system, maintaining complete traceability.

First, let’s get you access to a demo environment where you can experiment safely:

  1. Visit the demo: https://demo.string-theory.finance
  2. Create an account or use the provided demo credentials
  3. Note your API key - you’ll need this for making requests

Bruno is an open-source API client that we have configured with all String Theory endpoints, proper authentication, and example requests. This saves you from manually typing API calls and helps you explore the full API surface quickly.

  1. Install Bruno: Download from usebruno.com (it’s free!)
  2. Clone our Bruno collection:
    Terminal window
    git clone https://github.com/Ellisande/string-theory-bruno.git
  3. Open in Bruno: Use “Open Collection” and select the cloned folder
  4. Configure your environment:
    • Click the environment dropdown (top right)
    • Select “Configure” → “+Create”
    • Name it “Demo Environment”
    • Add variable base_url: https://demo.string-theory.finance
    • Add variable api_key: Your demo API key (mark as secret)
    • Save and activate

Let’s start with the most fundamental operation: depositing money into the system.

  1. Open the “deposit.bru” request in Bruno
  2. Update the request body with your demo values:
    • Change unitCount to 1000000 (for $1.00)
    • Try changing some of the other fields as well
    • Important: Replace owner:id in this request with your unique session ID: owner_735abf39.
  3. Click “Send” to execute the request
cURL Deposit Request
Terminal window
curl -X POST "https://demo.string-theory.finance/v2/deposit" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": {
"type": "demo_deposit",
"token": "first_try_123"
},
"actor": {
"type": "test_user",
"id": "curl_api_test"
},
"owner": {
"type": "test_owner",
"id": "YOUR_UNIQUE_ID"
},
"deposits": [
{
"amount": {
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 1000000
}
}
],
"tags": {
"purpose": "demo",
"source": "getting_started_guide"
}
}'

Deposit API Reference

  • Creates a $1.00 USD deposit owned by the test_owner with ID owner_735abf39
  • Uses idempotency to prevent duplicate deposits
  • Optionally, adds metadata like tags for tracking and categorization
Expected Response
{
"knots": [
{
"id": "knot_abc123...",
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 1000000,
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID",
"depositThreadId": "thread_xyz789...",
// ... more fields ...
}
],
"idempotentResponse": false
}

You may have noticed the idempotencyKey field in the request and the idempotentResponse field in the response. Idempotency is a guarantee that the effect of an operation will be applied exactly once, even if the request is sent multiple times. The idempotency key is how we identify if two requests are the same, and the idempotentResponse field informs a requester if the response was replayed from idempotency data. Strong idempotency is a core part of String Theory’s promises around data integrity.

Now let’s see what money is available:

  1. Open the “owner - fetch balances.bru” request
  2. Update the owner id in the request body to your unique session ID: owner_735abf39
  3. Click “Send”
cURL Balance Request
Terminal window
curl -X POST "https://demo.string-theory.finance/v2/owner/balance" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"owner": {
"type": "test_owner",
"id": "YOUR_UNIQUE_ID"
}
}'

Balance API Reference

  • Shows the current balances for the owner
  • Note that “balances” is an array - String Theory supports all currencies and even custom asset types
Expected Response
{
"balances": [
{
"amount": {
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 1000000
},
"knots": [
{
"id": "knot_abc123...",
"availability": "available",
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 1000000,
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID",
"depositThreadId": "thread_xyz789...",
// ... more fields ...
}
]
}
]
}

If you make this same request with a different owner ID than the one you used in the deposit request, the balance will likely appear as zero. Owners are the fundamental way assets are segregated in String Theory.

You may have noticed that the balance endpoint is a POST request. All String Theory endpoints are POST requests with highly-structured bodies. This is a deliberate design choice; highly-structured request data doesn’t play very nicely with GET requests.

You may have noticed that we didn’t provide an actor in the balance request. Actor is a required field for all mutating requests (that is, requests that result in a data change), but is not a field on read-only requests.

Let’s add the knot to a group. Groups help you organize and operate on related money.

  1. Open the “knots - alter groups.bru” request
  2. Update the request body:
    • Replace knotIds with the knot ID from your deposit response
    • Set groupsToAdd to [{"type": "wallet", "token": "demo_001"}]
    • Replace owner:id in this request with your unique session ID: owner_735abf39
  3. Click “Send”
cURL Group Request
Terminal window
curl -X POST "https://demo.string-theory.finance/v2/knots/alterGroups" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": {
"type": "demo_group",
"token": "first_group_123"
},
"knotIds": ["knot_abc123..."],
"groupsToAdd": [
{
"type": "wallet",
"token": "demo_001"
}
],
"actor": {
"type": "test_user",
"id": "curl_api_test"
},
"owner": {
"type": "test_owner",
"id": "YOUR_UNIQUE_ID"
}
}'

Alter Groups API Reference

  • Automatically creates a “wallet” group called “demo_001” (assuming it doesn’t already exist)
  • Adds the knot to the new group
  • Now, the deposited $1.00 is in the “demo_001” group and will be available for future operations that name the group as a source

We say that the knot is added to the group, but what is technically happening is a bit different. Since knots are immutable, we can’t actually add it to the group. Instead, we create a new knot with the same thread ID and mark the original knot as “stale”. Stale knots like this are retained for auditability, but operations are only ever applied to “current” knots.

Expected Response
{
"alteredKnots": [
{
"id": "knot_def456...",
"availability": "available",
"parentKnotId": "knot_abc123...",
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 1000000,
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID",
"depositThreadId": "thread_xyz789...",
// ... more fields ...
"groups": [
{
"id": "group_ghi789...",
"type": "wallet",
"token": "demo_001",
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID"
}
],
// ... more fields ...
}
],
// ... more fields ...
}

Tags can also be used to organize and identify money, but Groups are more powerful if you intend to operate on a set of knots without the need to select individual knot IDs.

Now that the money is in a group, we can operate on it without naming a specific knot. Let’s withdraw some money from the group.

  1. Open the “withdraw.bru” request
  2. Update the request body:
    • Change unitCount to 700000 (for $0.70)
    • Set sourceGroups to [{"type": "wallet", "token": "demo_001"}]
    • Replace owner:id in this request with your unique session ID: owner_735abf39
  3. Click “Send”
cURL Withdrawal Request
Terminal window
curl -X POST "https://demo.string-theory.finance/v2/withdraw" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": {
"type": "demo_withdraw",
"token": "first_withdraw_123"
},
"sources": {
"groupUnions": [
{
"type": "wallet",
"token": "demo_001"
}
]
},
"owner": {
"type": "test_owner",
"id": "YOUR_UNIQUE_ID"
},
"amount": {
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 700000
},
"actor": {
"type": "test_user",
"id": "curl_api_test"
},
"tags": {
"purpose": "demo",
"withdrawal_type": "partial"
}
}'

Withdraw API Reference

  • Splits the original $1.00 knot into a $0.70 knot and a $0.30 knot
    • Both knots are left in the “demo_001” group
  • Withdraws the $0.70 knot, changing its availability to “withdrawn”
    • Note that it’s still in the “demo_001” group, but because of the new availability, won’t be available for withdrawals or reflected in the balance.
  • The remaining $0.30 knot stays in the group and remains available for future withdrawals

Splitting a knot is a special mutation with several rules:

  • A split always creates exactly two new knots
  • The new knots always have the same asset class as the original knot
  • The new knots always have amounts adding up to exactly the original amount
  • Metadata can be added, but all other fields are copied from the original knot
  • A special split thread is created as the “root” of the thread for the requested amount

Splits occur regularly in the system as part of operations with a provided amount input.

Expected Response
{
"withdrawnKnots": [
{
"id": "knot_01k3hv...",
"availability": "withdrawn",
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 700000,
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID",
"depositThreadId": "thread_xyz789...",
"currentThreadId": "thread_qrs456...",
"current": true,
// ... more fields ...
"actionType": "withdraw",
// ... more fields ...
}
],
"remainingKnot": {
"id": "knot_01k3hs...",
"availability": "available",
"unitType": "currency_micros",
"unitToken": "USD",
"unitCount": 300000,
"ownerType": "test_owner",
"ownerId": "YOUR_UNIQUE_ID",
"depositThreadId": "thread_xyz789...",
"currentThreadId": "thread_xyz789...",
"current": true,
// ... more fields ...
"actionType": "split",
// ... more fields ...
},
"idempotentResponse": false
}

Let’s break down what we just accomplished and why it matters:

  • We deposited $1.00, creating a knot with ID knot_abc123...
  • This knot is immutable and represents exactly $1.00 USD
  • We added the knot to a “demo_wallet” group
  • This group now contains $1.00 and can be used for future operations
  • We withdrew $0.70 from the group
  • String Theory automatically split the original $1.00 knot into two parts:
    • One $0.70 knot that was withdrawn
    • One $0.30 knot that remains in the group and is still available
  • Every operation is recorded with complete traceability
  • You can see exactly where money came from and where it went
  • The thread ID tracks the complete lifecycle of the original $1.00

Unlike traditional systems where you “update” account balances, String Theory creates new knots for every change. This means:

  • Complete and verbose auditing
  • No risk of data corruption
  • Easy investigation
  • No retroactive changes

Traditional systems force you to choose one “account” for money. String Theory lets you:

  • Put money in multiple groups simultaneously
  • Create dynamic categorization
  • Build complex business logic with unlimited ways to view and operate on money

Using whole numbers (like 1,000,000 for $1.00) eliminates floating-point errors that plague financial systems. When you are ready, you can learn a lot more in the Amounts section.

Now that you have built up a bit of data and understanding, we encourage you to explore the UI and some advanced concepts in the next steps guide.

As you explore String Theory, you’ll likely have questions. Here are your resources:

  • Blog: Read our blog posts to learn more about the system and how it works
  • Documentation: Explore the concepts section for deep dives
  • API Reference: Check the API documentation for endpoint details
  • Bruno Collection: Use our pre-built requests to explore the API quickly
  • Support: Reach out to our team for personalized guidance