September 2026 release is live Read More

Add Business Context

Add Business Context

Business context attributes captured agent cost and usage to the customer, user, session, application, use case, request, region, or other reporting dimension that generated the activity.

Set context once around the relevant request, workflow, session, or job. Supported AI calls and metered operations created inside that boundary inherit the same values.

How context is inherited

Context flows inward from the block where it is set. Nested contexts merge with the outer context. If an inner context sets the same field or tag, the inner value takes precedence until that block ends.

Python and JavaScript / TypeScript use the same attribution model, but the trace representation differs slightly. withMvkContext() in TypeScript can create an mvk.context grouping span. Python mvk.context() applies the context without creating that additional grouping span.

Supported context fields

Field

Use

user_id / userId

End user or internal actor

user_email / userEmail

Email address when permitted by the organization's data policy

session_id / sessionId

Conversation or workflow spanning multiple operations

customer_id / customerId

Customer or account receiving the work

application_id / applicationId

Application or product surface

use_case / useCase

Business process being performed

request_id / requestId

Application request correlation ID

region

Runtime or business region

tags

Stable additional reporting dimensions

Every field is optional. Configure only the fields required for reporting or allocation.

Add context in Python

Python
import mvk_sdk as mvk

with mvk.context(
    customer_id="acme",
    user_id="user-123",
    session_id="session-456",
    use_case="customer_support",
    tags={"channel": "web", "team": "support"},
):
    run_agent()

Supported operations created inside the block inherit the context values.

Add context in JavaScript / TypeScript

TypeScript
import { withMvkContext } from '@mavvrikai/sdk';

await withMvkContext(
  {
    customerId: 'acme',
    userId: 'user-123',
    sessionId: 'session-456',
    useCase: 'customer_support',
    tags: { channel: 'web', team: 'support' },
  },
  async () => {
    await runAgent();
  },
);

Add context to a complete function

Use the decorator form when a function always belongs to the same business context.

Python

Python
@mvk.context(
    use_case="claims_adjudication",
    tags={"line_of_business": "commercial"},
)
def adjudicate_claim(claim_ref):
    return run_adjudication(claim_ref)

JavaScript / TypeScript

TypeScript
import { mvkContext } from '@mavvrikai/sdk';

class ClaimsService {
  @mvkContext({
    useCase: 'claims_adjudication',
    tags: { line_of_business: 'commercial' },
  })
  async adjudicateClaim(claimRef: string) {
    return runAdjudication(claimRef);
  }
}

TypeScript decorator syntax requires decorator support in the application configuration. Use withMvkContext() when decorators are not enabled.

Example: SaaS support agent

Python
@app.post("/chat")
async def chat(request: Request, message: str):
    with mvk.context(
        customer_id=request.headers["X-Customer-ID"],
        user_id=request.headers["X-User-ID"],
        session_id=request.headers["X-Session-ID"],
        use_case="customer_support",
    ):
        return run_support_agent(message)

This enables reporting by customer, support session, user, and use case.

Example: internal developer assistant

Python
with mvk.context(
    user_id="emp-4821",
    user_email="developer@example.com",
    use_case="developer_assistant",
    tags={"team": "platform", "env": "production"},
):
    answer = developer_agent.ask(question)

Use user_email only when the identity is appropriate for telemetry export and permitted by the organization's data policy.

Example: batch document processing

Python
for document in batch:
    with mvk.context(
        customer_id=document.customer_id,
        session_id=batch_id,
        request_id=document.job_id,
        use_case="document_processing",
    ):
        process_document(document)

A batch can share one session_id while each document uses a separate request_id.

Use nested context

Python
with mvk.context(
    customer_id="acme",
    session_id="session-456",
    tags={"team": "support"},
):
    classify_request()

    with mvk.context(
        use_case="refund_review",
        tags={"workflow_stage": "refund"},
    ):
        review_refund()

Nested contexts merge. An inner context overrides an outer value when both set the same field or tag.

Use context and signals for different purposes

  • Context identifies who or what the work belongs to.

  • Signal identifies a step that occurred in the workflow.

Do not create a custom signal only to repeat customer or session identity on an LLM call that Mavvrik already captures automatically.

Python
with mvk.context(
    customer_id="acme",
    session_id="session-456",
):
    with mvk.create_signal(
        name="ocr-document",
        step_type=MVKStepType.TOOL,
        operation="ocr",
        tool_name="textract",
    ):
        text = run_ocr(file)

    summary = client.chat.completions.create(...)

The OCR signal and automatically captured model call inherit the same customer and session context.

Configure tags

Use tags for stable categories that will be grouped across many executions.

team=support
channel=web
env=production
product=claims
line_of_business=commercial

Avoid high-cardinality tags such as request UUIDs, timestamps, raw user prompts, document IDs, or session IDs. Use first-class context fields for those identifiers where available.

Python tag rules include:

  • key: lowercase [a-z0-9._-], maximum 64 characters;

  • value: text, maximum 256 characters;

  • maximum 10 custom tags per span.

Python enforces these validation rules. JavaScript / TypeScript sends tags as configured, so use the same naming and cardinality discipline even where the SDK does not enforce the rule locally.

Do not use customer-defined tags beginning with mvk_, otel., or service. because they can collide with system attributes.

Configure global tags

Python
mvk.instrument(
    wrappers={"include": ["genai"]},
    tags={"env": "production", "region": "us-east-1"},
)

Request-level tags apply only inside the context:

Python
with mvk.context(tags={"team": "claims"}):
    run_agent()

Use global tags for deployment-level attributes and request context for per-request identity.

Add context in web applications

Set context as early as possible in request handling.

Python
@app.post("/claim")
async def claim(request: Request):
    with mvk.context(
        user_id=request.headers.get("X-User-ID"),
        customer_id=request.headers.get("X-Customer-ID"),
        session_id=request.headers.get("X-Session-ID"),
    ):
        return adjudicate_claim()

If work moves to another thread, process, queue, or background job, set the required context again inside that execution boundary.

Propagate context across services

Supported web integrations can carry context between services. Context can also be extracted explicitly on the receiving service.

Python:

Python
from mvk_sdk import extract_context_from_headers

ctx = extract_context_from_headers(request.headers)

JavaScript / TypeScript:

TypeScript
import { extractContextFromHeaders } from '@mavvrikai/sdk';

const ctx = extractContextFromHeaders(request.headers);

JavaScript / TypeScript can explicitly inject context into outbound headers:

TypeScript
import { injectContextIntoHeaders } from '@mavvrikai/sdk';

injectContextIntoHeaders(ctx, outgoingHeaders);

user_email is not propagated through Mavvrik context headers. Set it separately in each service that requires that identity.

For public traffic, strip or validate untrusted Mavvrik context headers at the gateway so external callers cannot control internal cost attribution.

Verify business context

  1. Run one request using a known session_id.

  2. Open Home → Agentic → Sessions.

  3. Search for the test session.

  4. Open a downstream AI or tool operation.

  5. Confirm the expected customer, user, session, use-case fields, and tags are present.

If an operation appears without context, confirm that the operation executed inside the context boundary. For asynchronous or background work, set the context inside the worker that performs the operation.