DocuLink.Studio.CustomerApi
0.5.0
dotnet add package DocuLink.Studio.CustomerApi --version 0.5.0
NuGet\Install-Package DocuLink.Studio.CustomerApi -Version 0.5.0
<PackageReference Include="DocuLink.Studio.CustomerApi" Version="0.5.0" />
<PackageVersion Include="DocuLink.Studio.CustomerApi" Version="0.5.0" />
<PackageReference Include="DocuLink.Studio.CustomerApi" />
paket add DocuLink.Studio.CustomerApi --version 0.5.0
#r "nuget: DocuLink.Studio.CustomerApi, 0.5.0"
#:package DocuLink.Studio.CustomerApi@0.5.0
#addin nuget:?package=DocuLink.Studio.CustomerApi&version=0.5.0
#tool nuget:?package=DocuLink.Studio.CustomerApi&version=0.5.0
DocuLink Studio Customer API — .NET SDK
Official .NET (C#) SDK for the DocuLink Studio Customer API — OCR / LLM
document processing, master data, and AI chat, with Socket.IO real-time and
SSE streaming. Targets net8.0.
🆕 What's new in 0.5.0
All-Process — hand the whole pipeline to the server instead of driving it yourself: pass
AutoProcessto the upload, or callallProcesson an uploaded scan (it also resumes one stuck at"3"/"5"). Then pollgetScanStatusuntilDone.scanDocumentnow defaults to this path and uses no Socket.IO at all, so it works from serverless functions, batch jobs and anything behind a firewall — passallProcess: falsefor the 0.4.x socket-driven behaviour.Human-in-the-loop —
editOutputRecord/deleteOutputRecordchange one row instead of PUT-ing the whole document back;getMappingCandidates/getMappingMeta/pickMappingCandidatelet you inspect and change the master-data row the engine matched;exportScanOutputandgetScanSourceFiledownload the result and the original file.listScansfinally lists scans across every task.⚠️
updateJsonOutputsaves a full-output override thatgetJsonOutputreturns in preference to the server's own output, so while one exists the record editors answer 409 on purpose — callclearOutputOverridefirst.Row-level master data — read/add/update/delete individual rows plus search, history and a validating import, instead of replacing the whole table.
Account self-service —
getMe, usage reports + export, invoices,rotateApiKeyandgetAuditLogs. Rotating the key revokes every previously issued token immediately; the SDK swaps in the new key and re-authenticates for you, but the key is shown only once — persist it.
⚠️ Breaking change in v0.4.0 — document status constants.
DocumentStatusnow matches the server's full lifecycle:"1"Uploaded,"2"/"3"OCR (processing/completed),"4"/"5"Schema,"6"/"7"Mapping,"9"Error —DocumentStatus.Completedchanged value from"4"to"7", andOcr/Schema/Mappingwere replaced by*Processing/*Completed. See the SDKCHANGELOG.md.
⚠️ Also in v0.4.0: the doc-scan
joinpayload is now the object{room}the server actually reads (bare-string joins were silently ignored — realtime never worked through 0.2.0–0.3.1);UploadParams.ReturnFormatTypetakes"1"/"2"(useReturnFormatTypeValue.Public/Customer), not"JSON"|"XML"|"CSV"; newScanDocumentAsyncpipeline helper +UpdateJsonOutputAsync.
⚠️ Breaking change in v0.3.0 — real-time subscription.
SubscribeDocumentScanAsync(...)now takes the TaskUUID (the task id you use for upload), not the DocumentScanUUID. The server broadcastsdoc-scanevents to roomdoc-scan-{TaskUUID}; a0.2.0subscription that passed the scan UUID received nothing. Each event's payloadUUIDis still the DocumentScanUUID. See the SDKCHANGELOG.md.
ℹ️ v0.3.1 —
SubscribeDocumentScanAsync(...)now sends theauth: { token }Socket.IO handshake the document server requires. Authenticate (or pre-set an access token) before subscribing; anonymous connects are rejected.
Install
dotnet add package DocuLink.Studio.CustomerApi
Quickstart
using DocuLink.Studio.CustomerApi;
using DocuLink.Studio.CustomerApi.Models;
var client = new DoculinkClient(new DoculinkOptions
{
ProviderApiKey = "your-35-char-provider-key",
CustomerApiKey = "your-35-char-customer-key",
Email = "customer@example.com", // optional
// BaseUrl defaults to the test environment; override for prod.
});
// Authentication is automatic on first call, but you can do it explicitly:
await client.AuthenticateAsync();
var usage = await client.GetUsageAsync();
Console.WriteLine($"Plan {usage.PlanCode}: {usage.QuotaRemaining}/{usage.QuotaPages} pages left");
HttpClientFactory
Pass your own HttpClient (it will not be disposed by the SDK):
var client = new DoculinkClient(options, httpClientFactory.CreateClient("doculink"));
Authentication & auto-refresh
POST /authwith your API keys returns an access token (~24h) and refresh token (~30d); both are stored on the client.- Every authenticated request sends
Authorization: Bearer <AccessToken>. - On a
401, the SDK refreshes the token and retries once; if refresh fails it re-authenticates with your API keys and retries once. - You may pre-set
AccessToken/RefreshTokeninDoculinkOptionsto skip the initial login.
Document processing & upload
var upload = await client.UploadFileAsync("task-uuid", new UploadParams
{
FileBytes = await File.ReadAllBytesAsync("invoice.pdf"),
FileName = "invoice.pdf",
ContentType = "application/pdf",
SchemaUuid = "schema-uuid",
ReturnFormatUuid = "return-format-uuid",
ReturnFormatType = ReturnFormatTypeValue.Public, // "1" public / "2" customer — ค่า Type ของ return format ที่เลือก (ไม่ใช่ชื่อ file format)
ClientUuid = null, // optional
});
var scanId = upload.DocumentScanUuid!;
// Drive the pipeline (or watch the socket for progress):
await client.OcrProcessAsync("task-uuid", scanId);
await client.SchemaProcessAsync("task-uuid", scanId);
await client.MappingProcessAsync("task-uuid", scanId);
var json = await client.GetJsonOutputAsync("task-uuid", scanId);
⚠️ Some billing rejections return HTTP 200 with
status:false— the SDK raisesApiExceptionfor these too. Always be ready to catch it.
Real-time — document scan progress (Socket.IO)
using DocuLink.Studio.CustomerApi.Realtime;
var realtime = new DoculinkRealtime(client.Options, () => client.AccessToken);
// Subscribe with the TaskUUID (the same :taskid you upload to) — NOT the
// DocumentScanUUID. One task room streams progress for every scan in the task;
// use the payload UUID (the DocumentScanUUID) to tell them apart.
using var sub = await realtime.SubscribeDocumentScanAsync(
taskId,
onUpdate: u => Console.WriteLine($"[{u.Uuid}] [{u.Status}] {u.CurrentLog}"),
onError: e => Console.Error.WriteLine(e));
// ... later: sub.Dispose(); disconnects.
Chat — SSE streaming (recommended)
var sessionId = await client.CreateChatSessionAsync();
var finalMessage = await client.SendChatMessageStreamAsync(
sessionId,
"How do I process a PDF?",
onEvent: e =>
{
if (!string.IsNullOrEmpty(e.Chunk)) Console.Write(e.Chunk);
});
Console.WriteLine();
Console.WriteLine(finalMessage.Content);
Chat — Socket.IO (option B)
using var chatSub = await realtime.SubscribeChatSessionAsync(sessionId, new ChatHandlers
{
OnStart = e => Console.WriteLine("start"),
OnChunk = e => Console.Write(e.Chunk),
OnEnd = e => Console.WriteLine($"\n{e.Message?.Content}"),
OnError = e => Console.Error.WriteLine(e.Error),
});
// Then send an async message (202); the reply arrives over the socket.
await client.SendChatMessageAsync(sessionId, "Hello");
Errors
All methods throw ApiException on failure:
try
{
await client.UploadFileAsync(taskId, p);
}
catch (ApiException ex)
{
Console.Error.WriteLine($"[{ex.StatusCode}] status={ex.Status}: {ex.Message}");
}
Documentation
Full HTML API reference: ../docs/index.html.
License
MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- SocketIOClient (>= 3.1.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.