Skip to content
.seventhings.com

Prefill your credentials

Fill in your non-secret values to have them appear in the examples below. Stored locally in your browser.

SDK Workflows

This page shows practical workflows that are the same in all official SDKs. For endpoint-level request and response schemas, use the API Reference.

Objects, rooms, locations, and persons use field keys configured in your seventhings instance. The SDKs therefore accept plain maps or arrays instead of fixed request models.

fields := map[string]any{
"inventory_name": "MacBook Pro 16",
"serial": "SN-123",
}
missing, err := c.MissingMandatoryFields(ctx, models.AssetTrackingTemplateAsset, fields)
if err != nil {
return err
}
if len(missing) > 0 {
// collect the missing instance-specific field keys before creating
}
uuid, err := c.ObjectCreate(ctx, fields)

Use models.AssetTrackingTemplateAsset, models.AssetTrackingTemplateRoom, or models.AssetTrackingTemplatePerson when reading field definitions.

use Seventhings\Models\Enums\AssetTrackingTemplate;
$fields = [
'inventory_name' => 'MacBook Pro 16',
'serial' => 'SN-123',
];
$definitions = $client->fieldDefinitions->list(AssetTrackingTemplate::Asset);
$uuid = $client->objects->create($fields);

In PHP, check the returned field definitions directly when you need to enforce mandatory instance-specific fields before creating a record.

from seventhings.models import AssetTrackingTemplate
fields = {
"inventory_name": "MacBook Pro 16",
"serial": "SN-123",
}
missing = client.field_definitions.missing_mandatory_fields(AssetTrackingTemplate.ASSET, fields)
if missing:
... # collect the missing instance-specific field keys before creating
uuid = client.objects.create(fields)
const fields = {
inventory_name: 'MacBook Pro 16',
serial: 'SN-123',
};
const missing = await client.fieldDefinitions.missingMandatoryFields('asset', fields);
if (missing.length > 0) {
// collect the missing instance-specific field keys before creating
}
const uuid = await client.objects.create(fields);

Use 'asset', 'room', or 'person' (or the AssetTrackingTemplate constants) when reading field definitions.

Objects, rooms, locations, rental cases, and CircularityHub list calls share the same page, perPage, sort, and filters model.

opts := models.NewListOptions().
WithPage(1).
WithPerPage(50).
SortBy("updated_at", models.SortDESC).
Where(models.Like("inventory_name", "Laptop"))
objects, err := c.ObjectsList(ctx, opts)

To walk every page, use one of the Go iterator helpers:

for object, err := range c.ObjectsAll(ctx, models.NewListOptions().WithPerPage(100)) {
if err != nil {
return err
}
_ = object["inventory_name"]
}
use Seventhings\Models\FilterEntry;
use Seventhings\Models\ListOptions;
use Seventhings\Models\Enums\FilterOperator;
use Seventhings\Models\Enums\SortDirection;
$page = 1;
$perPage = 50;
do {
$objects = $client->objects->list(new ListOptions(
page: $page,
perPage: $perPage,
sort: ['updated_at' => SortDirection::Desc],
filters: [
new FilterEntry('inventory_name', FilterOperator::Like, ['Laptop']),
],
));
foreach ($objects as $object) {
// process each object
}
$page++;
} while (count($objects) === $perPage);

The PHP SDK also provides all() generators that walk every page, for example $client->objects->all(new ListOptions(perPage: 100)).

from seventhings.models import ListOptions, SortDirection, like
opts = (
ListOptions(page=1, per_page=50)
.sort_by("updated_at", SortDirection.DESC)
.where(like("inventory_name", "Laptop"))
)
objects = client.objects.list(opts)
# Or walk every page (AsyncClient: `async for`):
for obj in client.objects.all(ListOptions(per_page=100)):
print(obj.get_str("inventory_name"))
import { Filter, SortDirection } from '@seventhingscompany/customer-api';
const objects = await client.objects.list({
page: 1,
perPage: 50,
sort: { updated_at: SortDirection.Desc },
filters: [Filter.like('inventory_name', 'Laptop')],
});

To walk every page, iterate with all():

for await (const object of client.objects.all({ perPage: 100 })) {
console.log(object.string('inventory_name'));
}

Upload a file first, then attach the returned file UUID to an attachment field on an object.

file, err := os.Open("manual.pdf")
if err != nil {
return err
}
defer file.Close()
fileUUID, err := c.FileUpload(ctx, "manual.pdf", file)
if err != nil {
return err
}
_, err = c.ObjectAddFiles(ctx, objectUUID, []models.FileAttachment{
{FieldKey: "documents", FileUUID: fileUUID},
})
use Seventhings\Models\FileAttachment;
$stream = fopen('manual.pdf', 'rb');
$fileUuid = $client->files->upload('manual.pdf', $stream);
$client->objects->addFiles($objectUuid, [
new FileAttachment('documents', $fileUuid),
]);
from seventhings.models import FileAttachment
with open("manual.pdf", "rb") as fh:
file_uuid = client.files.upload("manual.pdf", fh)
client.objects.add_files(object_uuid, [FileAttachment("documents", file_uuid)])
import { readFile } from 'node:fs/promises';
// upload() accepts a Blob, Uint8Array, ArrayBuffer, or ReadableStream.
const fileUuid = await client.files.upload('manual.pdf', await readFile('manual.pdf'), {
contentType: 'application/pdf',
});
await client.objects.addFiles(objectUuid, [{ fieldKey: 'documents', fileUuid }]);

Use the field definitions endpoint to discover which object fields are attachment fields in your instance.

Tasks use typed request models. A task must reference at least one asset and have at least one assignee.

deadline := "2026-12-31"
taskUUID, err := c.TaskCreate(ctx, models.CreateTask{
Title: "Review inventory",
Deadline: &deadline,
Assignees: []string{userUUID},
References: []models.TaskReferenceInput{
{Type: models.TaskReferenceTypeAsset, UUID: objectUUID},
},
Reminders: []models.TimeInterval{
{Unit: models.TimeIntervalDays, Value: 1},
},
})
if err != nil {
return err
}
err = c.TaskUpdateStatus(ctx, taskUUID, models.TaskStatusClosed)
use Seventhings\Models\CreateTaskRequest;
use Seventhings\Models\TaskReferenceInput;
use Seventhings\Models\TimeInterval;
use Seventhings\Models\Enums\TaskReferenceType;
use Seventhings\Models\Enums\TaskStatus;
use Seventhings\Models\Enums\TimeIntervalUnit;
$taskUuid = $client->tasks->create(new CreateTaskRequest(
title: 'Review inventory',
deadline: '2026-12-31',
assignees: [$userUuid],
references: [new TaskReferenceInput(TaskReferenceType::Asset, $objectUuid)],
reminders: [new TimeInterval(TimeIntervalUnit::Days, 1)],
recurringSchedule: null,
));
$client->tasks->updateStatus($taskUuid, TaskStatus::Closed);
from seventhings.models import (
CreateTask,
TaskReferenceInput,
TaskStatus,
TimeInterval,
TimeIntervalUnit,
)
task_uuid = client.tasks.create(CreateTask(
title="Review inventory",
deadline="2026-12-31",
assignees=[user_uuid],
references=[TaskReferenceInput(object_uuid)],
reminders=[TimeInterval(TimeIntervalUnit.DAYS, 1)],
))
client.tasks.update_status(task_uuid, TaskStatus.CLOSED)
import { TaskStatus } from '@seventhingscompany/customer-api';
const taskUuid = await client.tasks.create({
title: 'Review inventory',
deadline: '2026-12-31',
assignees: [userUuid],
references: [{ type: 'asset', uuid: objectUuid }],
reminders: [{ unit: 'days', value: 1 }],
});
await client.tasks.updateStatus(taskUuid, TaskStatus.Closed);

Use TaskListOptions (all SDKs) to list tasks by status, deadline range, assignee, author, or reference type.

Persons are asset-tracking records and can have instance-specific fields such as department, phone number, or custom fields. Users are login accounts.

  • Use persons when you need people as assignable or searchable records.
  • Use users when you need login-user metadata or task assignees.
  • Persons can be fetched by UUID or numeric ID in all SDKs.
  • Users can be listed, fetched by UUID, or fetched by numeric ID.
  • The customer API does not expose a direct create-user endpoint, but it can create a user from a person through the persons resource.
personUUID, err := c.PersonCreate(ctx, map[string]any{
"email": "max@example.com",
"first_name": "Max",
})
user, err := c.UserGetByID(ctx, 42)
$personUuid = $client->persons->create([
'email' => 'max@example.com',
'first_name' => 'Max',
]);
$user = $client->users->getById(42);
person_uuid = client.persons.create({
"email": "max@example.com",
"first_name": "Max",
})
user = client.users.get_by_id(42)
const personUuid = await client.persons.create({
email: 'max@example.com',
first_name: 'Max',
});
const user = await client.users.getById(42);

CircularityHub is the main exception to the SDKs’ UUID convention. Items and orders use integer IDs.

err := c.CircularityHubAddObjects(ctx, map[string]models.AddObjectEntry{
objectUUID: {Category: "Electronics", Price: "50.00"},
})
orderID, err := c.CircularityHubOrderCreate(ctx, []int{itemID})
order, err := c.CircularityHubOrderGet(ctx, orderID)
use Seventhings\Models\AddObjectEntry;
$client->circularityHub->addObjects([
$objectUuid => new AddObjectEntry(category: 'Electronics', price: '50.00'),
]);
$orderId = $client->circularityHub->createOrder([$itemId]);
$order = $client->circularityHub->getOrder($orderId);
from seventhings.models import AddObjectEntry
client.circularity_hub.add_objects({
object_uuid: AddObjectEntry(category="Electronics", price="50.00"),
})
order_id = client.circularity_hub.create_order([item_id])
order = client.circularity_hub.get_order(order_id)
await client.circularityHub.addObjects({
[objectUuid]: { category: 'Electronics', price: '50.00' },
});
const orderId = await client.circularityHub.createOrder([itemId]);
const order = await client.circularityHub.getOrder(orderId);

Use the integer ID returned by createOrder() for later order reads or updates.