Segments and the loop
Name a live filter over your Companies, read its members, refine it, and use what you learn.
A search answers a question once. A Segment keeps the question: a name and a filter over Companies your organization owns. Membership is live — whichever Companies match when you ask — rather than a snapshot that can go stale.
1. Open the population door
A registry predicate can only select Companies whose Legal entities your organization has
unlocked. Use the Commons' two-step search first: POST /api/v1/search evaluates the
population, then POST /api/v1/search/{searchId}/unlock mints every matched Legal entity as
a Company of your organization and unlocks it, 1 credit per Legal entity you have not
unlocked before.
That boundary is deliberate. A verified-but-locked Company never appears in a Segment, so reading a Segment cannot reveal Legal entity data you have not paid for. Search and unlock are the population door; every Segment operation is free.
2. Name the live filter
POST /api/v1/segments stores a name and a filter, and nothing else. It does not evaluate
the Commons or count the result.
{
"name": "Estonian software, high ICP",
"filter": {
"type": "group",
"logic": "AND",
"children": [
{
"type": "rule",
"fieldId": "core.country",
"operator": "equals",
"value": "EE"
},
{
"type": "rule",
"fieldId": "registry.revenueEur",
"operator": "greaterThan",
"value": 1000000,
"params": { "years": [2024] }
},
{
"type": "rule",
"fieldId": "research.icp_score",
"operator": "greaterThan",
"value": 7
}
]
}
}curl -X POST https://www.spore.ee/api/v1/segments \
-H "Authorization: Bearer $SPORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: segment-create-1" \
-d @segment.jsonA filter leaf names its origin in fieldId:
| Reference | Origin |
|---|---|
core.<field> | The Company's Core, such as core.country or core.domain |
<namespace>.<field> | A Catalog field declared by your organization, such as research.icp_score |
registry.<field> | Legal entity data in the Commons, such as registry.revenueEur |
Every name is validated against the organization's own generated vocabulary. An undeclared
Catalog field, unknown Core field, or unavailable registry field is refused rather than
silently matching nothing. GET /api/v1/catalog?section=filter reports the vocabulary the
same organization can use.
3. Read the Segment and its members
GET /api/v1/segments/{segmentId} returns the resource — its id, name, filter,
timestamps, and strong ETag. GET /api/v1/segments pages all your Segments newest first,
so an agent resuming work finds them instead of re-deriving them.
curl https://www.spore.ee/api/v1/segments/$SEGMENT_ID \
-H "Authorization: Bearer $SPORE_API_KEY"
curl "https://www.spore.ee/api/v1/segments?limit=50" \
-H "Authorization: Bearer $SPORE_API_KEY"Page the live population separately:
curl "https://www.spore.ee/api/v1/segments/$SEGMENT_ID/companies?limit=50" \
-H "Authorization: Bearer $SPORE_API_KEY"The response is { items, nextCursor, total }. items is one page, nextCursor is opaque
and continues the read, and total is the exact size of the whole matching set. The filter
is evaluated when you ask, so Companies entering or leaving the filter are reflected
without a rebuild. Every read is free.
4. Refine the question
PATCH /api/v1/segments/{segmentId} changes the name, the filter, or both. Read the Segment
first and send its current strong ETag in Spore-If-Match (the standard If-Match, like every
standard conditional header, is refused on writes); a stale value is refused with the current Segment and ETag. Editing the
filter changes membership immediately.
{
"segmentId": "26ef456b-9a86-4e6f-bbe3-6a7050da23de",
"name": "Estonian software, ICP over 8",
"filter": {
"type": "group",
"logic": "AND",
"children": [
{
"type": "rule",
"fieldId": "core.country",
"operator": "equals",
"value": "EE"
},
{
"type": "rule",
"fieldId": "research.icp_score",
"operator": "greaterThan",
"value": 8
}
]
}
}curl -X PATCH https://www.spore.ee/api/v1/segments/$SEGMENT_ID \
-H "Authorization: Bearer $SPORE_API_KEY" \
-H "Content-Type: application/json" \
-H 'Spore-If-Match: "1"' \
-H "Idempotency-Key: segment-update-1" \
-d @segment-update.json5. Land your own knowledge
POST /api/v1/record writes results your own systems produced onto a Company, under fields
you declared first with POST /api/v1/namespaces:
{
"companyId": "7f9c2a14-3b6e-4d51-9a2f-1c8e5b0d47a3",
"fields": [
{ "field": "icp.score", "value": 82 },
{ "field": "icp.rationale", "value": "Series A, hiring SDRs" }
]
}curl -X POST https://www.spore.ee/api/v1/record \
-H "Authorization: Bearer $SPORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: segment-record-1" \
-d @record.jsonThe batch is all-or-nothing and free. Values are checked against their declared types. Once the Facts land, a Segment whose filter names those Catalog fields reflects them on its next member read.
6. Enrich the matching Companies
POST /api/v1/enrich accepts one or more Companies named by opaque UUID. Page the Segment's
members, choose the Companies that need the tool, and submit those ids explicitly:
{
"tool": "domain-finder",
"intent": "Find domains for the matching Companies missing one",
"input": {},
"target": {
"companyIds": [
"8a7a0f13-fce0-4d97-a5f8-1950a49e7a63",
"5c91df6b-3d6f-48e0-9da8-39d551f94a6b"
]
},
"maxCredits": 500,
"priority": "urgent",
"dryRun": false
}curl -X POST https://www.spore.ee/api/v1/enrich \
-H "Authorization: Bearer $SPORE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: segment-enrich-1" \
-d @enrich.jsonEnrichment is priced; reading the Segment before and after it is not. Facts produced by the tool can make a Company enter or leave the Segment on the next read, just as recorded Facts can.
7. Delete deliberately
Deletion is permanent and is refused unless the query says confirm=true. Company Facts
are untouched: they belong to Companies, not to the Segment that selected them.
{
"segmentId": "26ef456b-9a86-4e6f-bbe3-6a7050da23de",
"confirm": "true"
}curl -X DELETE "https://www.spore.ee/api/v1/segments/$SEGMENT_ID?confirm=true" \
-H "Authorization: Bearer $SPORE_API_KEY" \
-H "Idempotency-Key: segment-delete-1"The whole cycle
search → search unlock → segment-create → page members → enrich or record → page members.
The paid doors acquire Legal entity data or run tools; creating, listing, reading, editing,
and deleting a Segment are free. The Segment always names the current question, and every
member read answers it against the Companies your organization owns now.
Search and filters
The company filter AST, the field vocabulary that defines it, and how canonical hashing makes an identical search free for 24 hours.
Enrichment lifecycle
What a launch does after you start it: lifecycle, the five outcomes, polling, partial failure, cancellation, and automatic refunds.