---
title: "Custom data"
description: "Attach arbitrary string key-value pairs to Inttegro objects for application-specific needs."
canonical: "https://studio.inttegro.com/api/custom-data"
format: inttegro-machine-docs/v1
language: "C#"
sdk_version: "v10.3.0"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/csharp/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 612
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "machine-only-decisions"
recommended_mcp_tools: ["create_order","update_order"]
estimated_tokens: 2943
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** Attach arbitrary string key-value pairs to Inttegro objects for application-specific needs. This C# representation uses the selected SDK's native names wherever Studio has a verified mapping.

### Five questions

#### Q1. Is Custom data the right source for this task?

Use this reference for attach arbitrary string key-value pairs to inttegro objects for application-specific needs. Keep the four decision rules below with its exact operations and fields; do not infer a broader workflow from endpoint order.

#### Q2. What is the first decision rule for use custom data as a narrow join key, not an application database?

Prefer a small external record ID that lets your system join an Inttegro
resource back to authoritative application data. Inttegro stores custom data
but does not interpret, index, query, or apply business logic to it.

#### Q3. What is the second decision rule for use custom data as a narrow join key, not an application database?

Every key and value is a string and the serialized object is limited to 25 KB.
Encode a boolean-like hint deliberately as text; do not send nested objects,
arrays, secrets, payment credentials, or large documents.

#### Q4. What is the third decision rule for use custom data as a narrow join key, not an application database?

An update replaces the complete custom-data object instead of merging keys.
Retrieve the current resource and merge locally before updating when existing
values must survive.

#### Q5. What is the fourth decision rule for use custom data as a narrow join key, not an application database?

Minimize disclosure. If Inttegro does not need the value to perform the
requested commerce operation, keep it in your own system.

### Recommended MCP assistance

Use these through an authenticated Inttegro MCP connection. This document remains the contract source.

- [`create_order`](https://studio.inttegro.com/machine/csharp/inttegro-mcp/tools.md#create_order) — action; exact user confirmation required. Creates an order for an existing customer from catalog product and price IDs. This tool never executes payment; finalize defaults to false.
- [`update_order`](https://studio.inttegro.com/machine/csharp/inttegro-mcp/tools.md#update_order) — action; exact user confirmation required. Updates selected mutable order fields. A supplied line-item list replaces the complete set; payment configuration and execution are excluded.

## Document content

# Custom data

Custom Data lets you attach string key-value pairs to Inttegro objects—orders, customers, payments, and more. Use it to store reference IDs, external system identifiers, or small amounts of supplementary information that your application needs but Inttegro doesn't use directly. This guide explains how Custom Data works, its constraints, and when to use it (or not).

## Use custom data as a narrow join key, not an application database

The four decision rules are in the machine preamble above.

## How it works

> **Warning:**
>
> **Avoid data leakage**: Custom data usage often leads to data
> leakage—developers store application-specific data in Inttegro that doesn't
> belong there. Only give Inttegro the data it needs to successfully perform the
> request. Your application's internal state, business logic, and implementation
> details should remain in your system. Inttegro should only receive what's
> necessary for payment processing, order fulfillment, and customer
> communication.

Custom data is a simple string-to-string map attached to Inttegro objects. You provide keys and values as strings, and Inttegro stores them with the object. When you retrieve the object later, the custom data comes back exactly as you provided it—Inttegro doesn't interpret, validate, or use this data for any purpose. The entire custom data object, when serialized to JSON, cannot exceed **25 KB**. Both keys and values must be strings—Inttegro returns a `400 Bad Request` error if you provide non-string values like numbers, booleans, arrays, or objects.

**Important design principle**: Good API integration design usually doesn't require storing data in custom data fields. Over-reliance on custom data often signals architectural issues that should be addressed at the application level. If you find yourself storing significant amounts of data or complex structures in custom data, contact our technical support team to discuss better approaches.

## When to use custom data

Use Custom Data sparingly for genuinely application-specific needs:

**Appropriate uses:**

- **External reference IDs** - Link Inttegro objects to records in your system (`internal_order_id`, `crm_customer_id`)
- **Simple flags** - Store boolean-like values as strings (`requires_gift_wrap: "true"`, `is_priority_customer: "yes"`)
- **Display hints** - Store presentational information (`customer_tier: "gold"`, `display_category: "electronics"`)
- **Tracking identifiers** - Associate analytics or marketing tracking codes (`utm_campaign`, `affiliate_code`)

**When NOT to use Custom Data:**

- ❌ Storing large amounts of data (use your own database)
- ❌ Complex nested objects or arrays (flatten to separate keys or store in your system)
- ❌ Frequently changing data (Custom Data updates require API calls)
- ❌ Data that needs to be queried or filtered (Inttegro doesn't index Custom Data)
- ❌ Sensitive information like passwords or full credit card numbers (security risk)

## Size constraints

**What counts toward the limit:**

- All key strings
- All value strings
- JSON formatting: `{`, `}`, `:`, `,`, `"` characters
- Whitespace in the serialized JSON

**Staying within the limit:**

- **Use short, meaningful keys** - `order_ref` instead of `internal_order_reference_identifier`
- **Avoid redundant data** - Don't duplicate information Inttegro already stores
- **Prefer underscored values** - `warehouse_code: "wh_accra_01"` instead of `warehouse_code: "Warehouse Location Accra Primary Facility"`
- **Don't store large text** - Descriptions, notes, or content belong in your database
- **Flatten nested data** - Use `address_line1`, `address_line2` instead of nested objects

## Attaching custom data

Include the `custom_data` parameter when creating or updating Inttegro objects:

**Attaching Custom Data — POST /orders/create**

```csharp
using Inttegro;

using var inttegro = new InttegroClient(
    Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.Orders.CreateAsync(new OrderCreateRequest {
  CustomData = new Inttegro.CustomData()
    .Set("fulfillment_warehouse", "WH-ACCRA-01")
    .Set("internal_order_id", "ORD-2025-1234")
    .Set("shipping_priority", "standard"),
  CustomerData = new CustomerData {
    Name = "Akua Mensah",
    EmailAddress = "akua@example.com",
    PhoneNumber = "+233544998605",
  },
  LineItems = new List<LineItemParams> {
    new LineItemParams {
      Type = Inttegro.LineItemType.Product,
      Product = new ProductDetailsParams {
        Name = "Utility Sneakers",
        Price = new Inttegro.PriceParams {
          Currency = Inttegro.Money.Currency.GHS,
          Value = 20000,
        },
        Quantity = 1,
        Type = Inttegro.ProductType.Physical,
      },
    },
  },
});
```

When you retrieve the object later, Custom Data is included in the response:

```json
{
  "order": {
    "id": "or_abc123",
    "status": "completed",
    "custom_data": {
      "internal_order_id": "ORD-2025-1234",
      "fulfillment_warehouse": "WH-ACCRA-01",
      "shipping_priority": "standard"
    }
  }
}
```

## Updating custom data

Updating Custom Data **replaces the entire Custom Data object**—it doesn't merge with existing values. If you want to preserve existing keys, retrieve the object first, modify the Custom Data, then update.

**Example: Adding a key while preserving existing data**

**Updating Custom Data**

```csharp
using Inttegro;

using var inttegro = new InttegroClient(
    Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.Orders.UpdateAsync(new OrderUpdateRequest {
  CustomData = new Inttegro.CustomData()
    .Set("fulfillment_status", "picked")
    .Set("fulfillment_warehouse", "WH-ACCRA-01")
    .Set("internal_order_id", "ORD-2025-1234")
    .Set("shipped_at", "2025-01-15T10:30:00Z")
    .Set("shipping_priority", "standard"),
  OrderId = "or_abc123",
});
```

## Objects that support custom data

Custom Data is available on the following Inttegro objects:

- **Orders** - Attach custom data at the order level when creating orders. Link to internal order management systems, tracking IDs, or fulfillment workflows.
- **Order line items** - Each product line item in an order can have its own custom data. Use this for SKU mappings, warehouse locations, or item-specific fulfillment instructions.
- **Customers** - Store CRM references, customer segments, loyalty tier information, or external system identifiers.
- **Products** - Add custom data when creating or updating products. Track internal catalog IDs, supplier references, or merchandising metadata.
- **Financial accounts** - Attach custom data to financial accounts (bank accounts, mobile money accounts) for reconciliation identifiers or internal classification.

Custom Data is supported on both create and update operations for these objects. Check the specific API reference documentation for parameter details.

## Design recommendations

**Keep it minimal**: The best integrations rarely use Custom Data. If you're storing more than 5-10 key-value pairs per object, reconsider your approach.

**Use your database**: Inttegro is not a general-purpose data store. Store application data in your own database and use Custom Data only for linkage.

**Avoid duplication**: Don't store data that Inttegro already provides (order status, customer email, payment amounts). Query the API for current values instead.

**Plan for limits**: Design assuming Custom Data might be unavailable or lossy. Your application should function without it.

**Contact support**: If you're unsure whether Custom Data is the right approach, or if you're hitting size limits, reach out to our technical support team. We can help you design a better solution.

## Related resources

- [Orders API](https://studio.inttegro.com/machine/csharp/api/orders.md#create-an-order) - Creating orders with Custom Data
- [Customers API](https://studio.inttegro.com/machine/csharp/api/customers.md#create-customer) - Adding Custom Data to customer profiles
- [Products API](https://studio.inttegro.com/machine/csharp/api/products.md#create-a-product) - Attaching Custom Data to products
- [Financial Accounts API](https://studio.inttegro.com/machine/csharp/api/financial-accounts.md#create-a-financial-account) - Custom Data on payment destinations
- [Errors](https://studio.inttegro.com/machine/csharp/api/errors.md) - Handling validation errors for Custom Data
