Developers

One engine, four ways in.

Every surface runs the same deterministic operations. Pick the one that fits where your documents are allowed to go and where your code runs.

The connector

Use the service from a developer tool

https://api.docuoria.com/mcp

Add it as a remote MCP server in the tool's settings and sign in with the one-time passcode when it asks. The tool uploads documents from its sandbox to the service, where they are read by no model, refused after 24 hours and gone within 48. Templates (the document types a person sees in the account) and ledgers belong to your organisation and are shared with every assistant and flow on the team. The per-platform steps, written for an agent to follow, are at api.docuoria.com/install.

The local host

Keep documents on the machine

The local host serves the same operations as an MCP server on your machine. Your tool starts it, and documents are read by path and never uploaded.

  1. Install the command line tool

    $ dotnet tool install -g Docuoria.Cli   # .NET 10 or later

    The package is MIT.

  2. Register it with your tool, in the project folder

    ToolCommand
    Claude Codedocuoria init --tools claude
    Cursordocuoria init --tools cursor
    VS Code with GitHub Copilotdocuoria init --tools github-copilot
    Codexdocuoria init --tools codex
    Windsurfdocuoria init --tools windsurf
  3. Sign in once on this machine

    $ docuoria login
  4. Check

    $ docuoria doctor

docuoria init writes the server entry into the tool's own settings and records where templates live: your organisation's account by default, or the project folder with --store folder.

docuoria login signs in by device code and stores a seat credential labelled with the machine's name. The first time, accept the terms in the browser; login stops until you do, then run it again. The computer then appears under Your computers in your account (an owner sees every computer on the Team page); revoke it there or run docuoria logout. docuoria doctor reports the service, the store, the credential, the licence, and the registered tools.

Documents never leave the machine. Templates go to the account, or stay in the project folder. Licence use goes to Monaiq, aggregated; the host needs Monaiq about once an hour while extracting.

CommandDoes
docuoria list-toolsLists the supported tools and which are registered in this project
docuoria license statusShows the plan, allowances, and windows of the machine's seat
docuoria store pushCopies templates from the project folder to the account store
docuoria logoutRevokes the machine's credential

REST routes

Calling the routes from Power Automate, n8n or your own code

Every operation is a REST route on the service, described at api.docuoria.com/openapi.json. A flow authenticates with a connection key instead of a sign-in.

An owner creates and revokes keys on the Team page, or from the command line; a member asks an owner. The key is shown once, starts with dk_, and is sent as Authorization: Bearer dk_.... A revoked key's next call is refused with 401.

$ docuoria account keys create --label "My flow"
shell
curl -X POST "https://api.docuoria.com/extract?template=vendor-invoice&ledger=vendor-bills&format=json" \
  -H "Authorization: Bearer dk_..." \
  -H "Content-Type: application/pdf" \
  -H 'Content-Disposition: attachment; filename="vendor-messageId.pdf"' \
  --data-binary @invoice.pdf

To send the PDF in two steps, open a ticket with POST /uploads, send the file with PUT /uploads/{ticket} using the ticket's token and a Content-Disposition header, then call POST /extract with JSON {"document":"<id>","template":"vendor-invoice"}, where the id is the upload receipt's documentId.

Reading the result

A document that does not extract is still HTTP 200. Branch on status (extracted, partial or no-match), then on ledger.action: a row was written only when it is appended, and ledger is null unless status is extracted. Name the template with template=<id>; without it, a document extracts only when it strongly matches one of your saved templates, and a new organisation has none. Add ledger=<id> and format=json to the query; the first document extracted into it creates the ledger, and until then GET /ledgers/{id} answers 404. The result carries output, ledger.rowsAdded and ledger.totalRows.

File names

The file name comes from the Content-Disposition header, as attachment; filename="vendor-messageId.pdf", and is the ledger's key for a document it has seen. A second invoice.pdf returns 200 with ledger.action already-present and no row, although the PDF was read again. Name each file uniquely.

Reading a ledger

GET /ledgers/{id} returns the CSV in content up to 200 KB. Above that, content is null and downloadUrl is a single-use link, GET /downloads/{id}, valid for 10 minutes: fetch it at once.

Authoring over REST

Author a template over REST, in this order: GET /reference for the rules, POST /inspect with the PDF, write the template JSON, POST /validate-template, POST /dry-run with the PDF, then POST /templates to save it. Extract with the saved id as template.

Rate limits

On Free, execute and ledger-append calls are limited to 20 a minute. Run a flow one document at a time, and retry after a delay on 429 and 503.

Errors

A refused call returns application/problem+json with code, title and detail. A 401 means a missing or revoked key; owners manage keys on the Team page. A 402 means the organisation holds no live plan; see the Plan page in your account. A 429 means the allowance or the minute window is spent; wait and retry.

GroupRoutesPurpose
DocumentsPOST /uploads, PUT /uploads/{ticket}, GET /documents, DELETE /documents/{id}Hand PDFs to the account; a ticket lets a sandbox add files for 10 minutes
ExtractionPOST /extract, POST /classify, POST /batch, GET /jobs/{job}, GET /downloads/{id}Run a template, pick one, or queue a folder; large results come back as a link that lasts 10 minutes
AuthoringPOST /inspect, /test-patterns, /validate-template, /evaluate-match, /dry-run, /survey, /regression-checkEverything the assistant uses to write and check a template
TemplatesGET, POST /templates; GET, PUT, DELETE /templates/{template}The account store. JSON only; any other body is refused with 415
LedgersGET /ledgers, GET /ledgers/{ledger}, POST /ledgers/{ledger}/entries, DELETE /ledgers/{ledger}Running spreadsheets that append without duplicates
AccountGET /account, GET /referenceOrganisation and seats, and the guidance the assistant reads

MCP tools

Twenty-four tools, the same on the service and the local host

One MCP tool and one REST route per operation, with deterministic JSON results.

GroupTools
Documentscreate_upload, list_documents, delete_document
Extractionextract, classify, batch_extract, job_status
Authoringinspect, test_patterns, validate_template, evaluate_match, dry_run, survey, regression_check
Templatessave_template, list_templates, load_template, delete_template
Ledgersread_ledger, list_ledgers, append_ledger_rows, delete_ledger
Accountaccount, reference

The .NET SDK

From the package to the first result

The Docuoria package on NuGet targets .NET 10. A test in the SDK suite, ReadmeWalkthroughTests, compiles and runs this walkthrough, so it matches the shipped API.

$ dotnet add package Docuoria
csharp
using Microsoft.Extensions.DependencyInjection;
using Docuoria.Configuration;
using Docuoria.Contracts;
using Docuoria.MatchRules;
using Docuoria.Models;
using Docuoria.Output.Csv;
using Docuoria.Pipeline.Extraction;
using Docuoria.Pipeline.Publish;
using Docuoria.Registration;
using Docuoria.Results;

var services = new ServiceCollection();
services.AddDocuoriaEngine(b => b.AddBuiltInMatchRules().AddCsvOutputGenerator());
var engine = services.BuildServiceProvider().GetRequiredService<IDocuoriaEngine>();

var schema = new RecordDefinition("Invoice", new FieldDefinition[]
{
    new PrimitiveFieldDefinition("vendor", FieldType.String, isRequired: true),
});
var template = TemplateBuilder.Create("quickstart", new DataModel(schema))
    .WithMatchRule<FileNameMatchRule, FileNameMatchRuleConfiguration>(
        new FileNameMatchRuleConfiguration { Pattern = "**/*.pdf", Threshold = 1m })
    .ExtractWith<ExtractionStep, ExtractionStepConfiguration>(new ExtractionStepConfiguration(new IFieldMapping[]
    {
        new FieldMapping("vendor", FieldType.String, MetadataFieldExtractionSource.Standard(MetadataField.Title)),
    }))
    .PublishWith<PublishStep, PublishStepConfiguration>(new PublishStepConfiguration())
    .Build();

await using var pdf = File.OpenRead("invoice.pdf");
var result = await engine.ExecuteTemplateAsync<CsvOutputGenerator, CsvGeneratorOptions>(pdf, template, new CsvGeneratorOptions());
if (result is SucceededResult ok)
    Console.WriteLine(System.Text.Encoding.UTF8.GetString(ok.Output.Payload.Span));
csharp
switch (result)
{
    case SucceededResult success:   // success.Output.Payload, success.Output.ContentType
    case FailedResult failure:      // failure.StepIdentifier, failure.ErrorMessage
    case RejectedResult rejection:  // rejection.Reason, rejection.Detail
}

Deterministic and stateless

Same PDF, same template, same options produce the same bytes, which E2E_DeterminismTests proves on every build. The engine holds no per-call state; register it as a singleton and call it concurrently. No model runs anywhere in it.

Three result types

Succeeded carries the sealed output and its content type. Failed names the step and the error. Rejected carries the reason and detail. Each has a dry-run variant.

Your organisation's templates, from your own application

The service keeps each organisation's templates in its account store. On Pro and Pay-as-you-go, the SDK reads and writes that store with a connection key, so an engine in your application shares templates with every assistant and flow in the organisation.

csharp
services.AddDocuoriaEngine(b => b.AddApiTemplateStore(
    new Uri("https://api.docuoria.com/"),
    new ApiTemplateStoreCredentials { BearerToken = "<connection key>" }));

Only template JSON crosses the wire. The template routes refuse any other body with 415, and PrivacyInvariantTests fails the build if that changes.

Capabilities

What a template is made of

A template names how a document is recognised, where each value is read from, how values are transformed, and how the record is written out.

CategoryCountItems
Match rules7FileName, Metadata, TextPattern, TextAnchor, PageGeometry, Table, Composite
Extraction sources5 and a fallbackTextPattern, TextAnchor, MetadataField, TableCell, TableRows; Fallback
Pipeline steps5Extraction, Transformation, Retrieval, Python, Publish
Field transforms6Trim, Cast, Format, Rename, Compute, CollectionElement
Field types6String, Number, Integer, Boolean, Date, Timestamp
Output formats2CSV, JSON
Engine methods9EvaluateMatchRule, ExecuteTemplate, Inspect, TestPattern, TestGroups, DryRun, EvaluateMatch, Classify, ClassifyRanked
Result types3Succeeded, Failed, Rejected, each with a dry-run variant

The Retrieval and Python steps are on no hosted plan; a self-hosted deployment or an SDK host enables them by its own choice. XML output is on the roadmap.

Limits per 60 seconds

Each plan bounds how many calls of an operation go through in a 60-second window. Pay-as-you-go has Pro's windows. A spent window is refused before the work, and nothing is billed past the cap. The monthly allowances are on the pricing page.

OperationFreePro and Pay-as-you-go
execute20120
classify60360
batch-execute330
ledger-append20120
survey530
regression-check530
Authoring calls: inspect, test-patterns, evaluate-match, dry-run, validate-template, create-upload30300

Hosting modes

Four places the same engine runs

ModeWhat it isYour documentsStatus
Multi-tenantThe Docuoria service at api.docuoria.com, operated by SidubUploaded by you or your flow; read by no model; refused after 24 hours and gone within 48; deleted at once on requestAvailable now. Free, Pro, and Pay-as-you-go
On your machineThe local host, started by your developer toolNever leave the machineAvailable now. Any plan
Self-hostedThe same service deployed from the same Bicep into your own Azure subscription, operated by youNever leave your organisation's subscriptionBy arrangement. Its own offering
Single-tenantOne deployment per customer in Sidub's subscription, on your hostnameProcessed in your organisation's own deployment; deleted within 48 hours or on requestA later phase. By arrangement

The three cloud modes run the same code from the same Bicep; the mode sets whose subscription holds it and which hostname the connector carries. Licence validation and aggregated usage counts go to Monaiq in every mode. To arrange a self-hosted or single-tenant service: inquiries@sidub.net.

The account, from the command line

Owner commands

An owner manages the organisation in the account at /manage, or with these commands. Each signs the owner in by device code.

CommandDoes
docuoria account showLists the organisation's purchases and seats
docuoria account upgradePrints the checkout link for Pro; checkout completes in the browser
docuoria account seats add NAdds N seats to the organisation
docuoria account associate CODEAttaches a purchase code from the Monaiq marketplace to the organisation
docuoria account keys create --label "..."Creates a connection key for a flow, shown once

Licensing

Licence terms

The SDK and the Docuoria service are licensed under the Sidub Proprietary Software License Agreement, published verbatim as the License Agreement and canonical at sidub.ca/licensing. The licence type your organisation holds is the one its purchase names. The command line package on NuGet is MIT. Every plan, including Free, is a licence the service validates on each request. Plans and allowances are on the pricing page, and the limits per 60 seconds are under Capabilities. The account template store from the SDK (the SDK section) is on Pro and Pay-as-you-go, not on Free. Volume and OEM terms: inquiries@sidub.net.

Release status

What is live today

Docuoria 1.3.2 is the current release, on the service and NuGet. Items not yet verified may change.

Live todayThe service and its connector, the local host, the REST routes, the SDK, and the three plans
VerifiedSix journeys run end to end on real invoices and receipts in CAD and USD and checked against hand-verified values: a first document, the same document type again, a mixed-vendor folder, exactly the fields a system imports, a running ledger, and invoices told apart from receipts
Not yet verifiedBank and credit card statements, government and regulatory forms, recurring reports, email attachment automation, ERP and accounting integrations, purchase orders
May change on noticePlan prices and limits (Terms of Service, section 8)
Supportsupport@sidub.net. The software is provided as is (Terms of Service, section 10)

Shipped in 1.3.2

  • The service and the connector
  • Organisations and seats
  • Account template stores and ledgers
  • REST routes with connection keys
  • The local host for five developer tools
  • The engine and its authoring tooling
  • Batch jobs
  • The Free, Pro, and Pay-as-you-go plans

Next

  • Self-hosted service
  • Single-tenant service
  • Template improvement suggestions
  • Email attachment automation
  • ERP and accounting integrations
  • XML output
  • Additional match rules

Later

  • Client SDKs for the REST routes
  • Template generation from a sample PDF

Docuoria 1.3.2 is on the service and NuGet.

For questions, or a tool you want supported next, write to support@sidub.net.