Skip to content
API pagesStatus and month-end completeness

API documentation

Status and month-end completeness

This page covers the routes that answer "where does this month stand": the credential echo you call first, the completeness picture the whole product is judged by, the suppliers that are late by their own habits, and how often the digest email goes out.

Completeness is the core promise. Everything else in Syllevo exists to make these numbers reach zero missing.

Routes

Method Path Needs
GET /v1/status Any credential
GET /v1/completeness Any member
GET /v1/profiles/{profileId}/completeness View
POST /v1/profiles/{profileId}/completeness/expected ManageDocuments
POST /v1/profiles/{profileId}/completeness/expected/{id}/waive ManageDocuments
POST /v1/profiles/{profileId}/completeness/recompute ManageDocuments
GET /v1/predictions/missing Any member
GET /v1/digest-preferences Any member
PUT /v1/digest-preferences Any member

GET /v1/status

Tells you who the API thinks you are. Call it first when something is not working.

Field Type Means
actor string How you were recognized
organizationId uuid or null The organization the request is scoped to
correlationId string or null The id this request is filed under in the logs
{
  "actor": "apikey",
  "organizationId": "11111111-1111-4111-8111-111111111111",
  "correlationId": "c0ffee00-1111-4111-8111-111111111111"
}

actor is one of anonymous, session, apikey, mcp, or system. It is a lowercase word, not a number, which makes it one of only two enums in the whole API that are not integers. See Conventions.

This route is not organization scoped, so it answers without X-Organization-Id. A session token sent without that header comes back with organizationId: null, which is the fastest way to tell a missing header from a bad token. An API key always reports its own organization.

A wrong path does not answer 404 here or anywhere else. It answers 401, because the authorization fallback runs before routing decides there is nothing to route to. If /v1/status answers 200 and your route answers 401, check the spelling of the path before you check the credential. See Authentication.

Completeness, in one paragraph

Syllevo keeps a list of documents it expects for each client and each month, then matches arrivals against it. Three things put a row on that list: a supplier that bills this client most months, a person who typed it in, and a connected source that normally delivers and delivered nothing. Each row is missing, received, or waived. The missing ones are what reminders chase.

GET /v1/completeness

The firm's month in one answer, worst client first.

Parameter Type Means
period string The month as "2026-08". Omitted means the month running now
Field Type Means
period string The month this answer is about
profileCount integer How many clients are counted
profilesWithMissing integer How many of them are still short something
expectedCount integer Rows expected in total
receivedCount integer Rows satisfied
missingCount integer Rows still owed
waivedCount integer Rows written off
profiles array One summary per client, worst first

Each summary carries profileId, profileName, expectedCount, receivedCount, missingCount, and waivedCount.

There is no permission parameter and no organization parameter. The service narrows the query to the clients this caller was granted, so a member with three clients gets a number covering three clients, not the firm.

expectedCount is not receivedCount + missingCount + waivedCount in every case. Take the four counts as given rather than deriving one from the others.

GET /v1/profiles/{profileId}/completeness

One client's month, with the actual list.

Parameter Type Means
period string The month as "2026-08". Omitted means the month running now
Field Type Means
profileId uuid The client
profileName string Its name
period string The month
expectedCount integer Rows expected
receivedCount integer Rows satisfied
missingCount integer Rows still owed
waivedCount integer Rows written off
missing array The rows still owed
settled array The rows received or waived

The expectation shape

Field Type Means
id uuid The expectation
state ExpectedDocumentState 0 missing, 1 received, 2 waived
reason ExpectedDocumentReason Why it is expected. See below
supplierId uuid or null The supplier it is expected from
supplierName string or null That supplier's name
accountId uuid or null The source, on source-gap rows
accountProviderType DataProviderType, null What kind of source that is
accountTag string or null Its label
description string or null What somebody typed when they marked it
isRecurring boolean Whether it is asked again next month
satisfiedAt date-time, null When it was matched
satisfiedByDocumentId uuid or null The file that satisfied it
satisfiedByInvoiceId uuid or null The invoice that satisfied it
waivedAt date-time, null When it was written off
waiveReason string or null Why
createdAt date-time When the expectation appeared

reason:

Value Name Means
0 RecurringSupplier This supplier billed the client in most recent months
1 ManualMark Somebody said so
2 SourceGap A source that normally delivers delivered nothing this month

A 2 row is different from the others: what is missing is not a named supplier but everything that inbox or e-Factura connection usually carries, which is why it hangs off accountId instead of supplierId.

A 1 row outranks a 0 row wherever both would produce an expectation for the same supplier and month. A person who typed it in knows something the invoice history does not.

State 1 received is never set without a link. An expectation that claims a document arrived but cannot say which one is how a month closes on a document nobody has.

The shipped thresholds behind 0 are three months of lookback and at least two of them present, and behind 2, two months of lookback with documents in at least two. They are configuration rather than constants, so a deployment can tune them. They are deliberately forgiving in one direction: expecting too much costs an accountant ten seconds to waive, and expecting too little says a month is complete when it is not.

POST /v1/profiles/{profileId}/completeness/expected

Adds an expectation by hand. ManageDocuments. The "this client gets a rent invoice every month, chase it" route.

Field Type Required Means
supplierId uuid or null no The supplier it is expected from
description string or null no What it is, when no supplier row fits
period string or null no The month. Omitted means the month running now
isRecurring boolean no Ask again every month

Answers 201 with the expectation, and a Location header pointing at the month it now belongs to: /v1/profiles/{profileId}/completeness?period=2026-08. There is no route that reads a single expectation, so the month is where you look to see what you just created.

This answered 200 before 2026-09-11. If your client checks for 200 specifically, it now sees a 201 and has to accept it. Check for 2xx. See Changelog.

Marking something the recurring rule had already guessed takes over that row rather than adding a second one, and the answer is still 201: either way the row in the body is standing now and was not before the request.

isRecurring: true is the useful one. It carries forward, so the rent invoice is asked for again next month without anyone marking it again.

POST /v1/profiles/{profileId}/completeness/expected/{id}/waive

Says a document is not coming, so it stops appearing as missing. ManageDocuments.

Field Type Required Means
reason string or null no Why, kept on the row
stopRecurring boolean no Also stop asking in future months

Answers 200 with the expectation, now in state 2.

Waiving is per month, not forever. Next month asks again unless you send stopRecurring: true. That is the difference between "no invoice this January" and "we dropped this supplier".

An expectation id that belongs to another client cannot be addressed at all: the service proves the row belongs to the client in the path before it acts, so a mismatched pair answers 404.

POST /v1/profiles/{profileId}/completeness/recompute

Works the month out again from invoice history, standing marks, and source activity, and answers with the result. ManageDocuments. Takes the same optional period query parameter.

You should rarely need this. Completeness recomputes on its own as documents arrive. Call it after you have changed something the heuristics read, a merged supplier or a newly connected source, and you do not want to wait.

GET /v1/predictions/missing

Suppliers that are late by their own habits. Different from completeness: this is not "we expect this document", it is "this supplier bills you every month and it is past the day it usually does".

Parameter Type Means
profileId uuid Narrow to one client
page integer Default 1
pageSize integer Default 25, clamped to 200

Most overdue first. Paged like everything else, see Conventions.

Field Type Means
profileId uuid The client being billed
supplierId uuid The supplier
supplierName string or null Its name, null only if the supplier row is gone
usualDay integer The day of the month it usually bills by
expectedByDay integer The day the grace period ran out
monthsPresent integer How many lookback months it billed in
lastInvoiceIssueDate date When it last billed this client
lastInvoiceTotalAmount decimal What that last invoice came to
currencyCode string The currency of that invoice, ISO 4217

There is no sentence in this response, on purpose. The screen writes "Orange usually arrives by the 5th, it is the 12th, and nothing yet" for itself, from usualDay, expectedByDay, and today's date, in the reader's own language. An API that ships the sentence ships it in one language.

The rule is conservative. A supplier has to have billed in at least four of the lookback months before anything is said about its silence, usualDay is the 80th percentile of the days it actually billed on rather than the median, there are two days of grace on top, and expectedByDay never lands past the 28th so a short February cannot quietly drop a supplier off the list. A supplier the rule stays quiet about costs an accountant nothing. A supplier it is wrong about means a client gets told they forgot something they never owed.

profileId narrows within what the caller can already see. A client the caller cannot see is an empty page, never a 403.

Digest preferences

The digest is the email that says what is still missing. These two routes set how often the caller gets it, in the organization they are working in. It is a personal setting, not a firm one: two people in the same firm can hold different frequencies.

GET /v1/digest-preferences

{ "frequency": 0 }

PUT /v1/digest-preferences

Field Type Required Means
frequency DigestFrequency yes 0, 1, or 2
Value Name Means
0 Weekly Monday morning, covering the seven days behind it. The default
1 Daily Every morning, covering the day behind it
2 Off Nothing

Answers 200 with the frequency that now stands.

2 is honored without exception. There is no transactional carve-out that keeps sending digests to somebody who turned them off.