SDK Development
Universal Behavioral Contract
Every SDK must implement the same public API regardless of language. This ensures consistent behavior for users switching between languages.
Required Methods
| Method | Description |
|---|---|
SDK(apiKey, options?) | Constructor — initializes the SDK |
middleware() | Returns HTTP middleware that instruments all requests |
service(name, fn) | Wraps fn in a service:{name} span |
controller(name, fn) | Wraps fn in a controller:{name} span |
call(name, fn) | Wraps fn in an external:{name} span |
log(level, message) | Emits a structured log entry |
flush() | Manually flushes all buffered traces and logs |
close() | Stops background flusher and flushes remaining buffer |
Required Options
| Option | Default | Description |
|---|---|---|
baseURL | https://ingest.upblit.com | Ingest endpoint base URL |
flushInterval | 30 (seconds) | How often to auto-flush |
Middleware Behavior
The middleware must:
- Skip
GET /health— do not trace health check requests - Generate a
traceId(UUID v4) androotSpanId(UUID v4) per request - Store both in async-local / thread-local / context storage
- On response finish: push the root span to the trace buffer with:
requestMethod:"controller:{HTTP_METHOD}"(e.g.,"controller:POST")requestURL: the request pathresponseStatus: the HTTP status codedurationMs: wall-clock time from request start to response finishparentSpanId:null(root span has no parent)
Span Helper Behavior
Each span helper must:
- Read the current
spanIdfrom context asparentSpanId - Generate a new
spanId - Set the new
spanIdas current in context - Execute
fn() - On completion (success or error): push span to buffer, restore
parentSpanIdas current - On error: set
responseStatus = 500
Transport
POST {baseURL}/ingest/traces
POST {baseURL}/ingest/logs
Header: x-api-key: {apiKey}
Header: Content-Type: application/jsonPayload:
{
"timestamp": "<ISO8601 flush time>",
"traces": [...]
}Testing Your SDK
Every SDK should have tests covering:
- Middleware creates root span with correct fields
-
service()/call()create child spans with correctparentSpanId - Context propagation works across async calls
- On flush failure, batch is re-queued (not dropped)
-
fatallog level triggers immediate flush -
close()flushes remaining buffer before stopping
Ingest URL
All SDKs must use https://ingest.upblit.com as the default base URL.
Current inconsistency: The Go SDK uses
ingest.upblit.comand the Python SDK usesingest.upblit.dev. Both need to be aligned toingest.upblit.com.
Adding a New SDK
- Create the directory:
Upblit/sdk/<language>-sdk/ - Implement the universal behavioral contract
- Write tests
- Write a README with installation, quickstart, and API reference
- Publish to the appropriate package registry
- Add a documentation page at
docs/src/app/docs/sdks/<language>/page.mdx
Last updated on