Skip to content

How to Build Per-Account API Mappings: Field Discovery, Caching & Schema Drift

Learn how to architect per-account API mappings to handle custom fields, cache metadata against rate limits, and monitor for schema drift without hardcoding.

Nachi Raman Nachi Raman · · 19 min read
How to Build Per-Account API Mappings: Field Discovery, Caching & Schema Drift

Every B2B SaaS company eventually hits the same wall. You build a unified integration for a CRM or HRIS, standardize the data model, and ship it. It works perfectly for 80% of your SMB customers. Then, your sales team lands a massive enterprise prospect. The technical evaluation goes flawlessly until their Salesforce administrator hands you their schema.

Your unified data model just flattened a prospect's 147 custom Salesforce fields into first_name, last_name, and email. They rely on a highly mutated Deal_Registration__c custom object with nested relationships, Revenue_Forecast__c rollup fields the CFO watches quarterly, and an Industry_Vertical__c picklist that drives their entire routing logic. Your standardized API drops all of this data.

The deal is dead. And the problem isn't your core product—it's that your integration architecture lacks the ability to handle bespoke enterprise schemas.

To save these deals, engineering teams often fall into a technical debt trap: writing bespoke scripts just for this customer. Suddenly, your codebase is littered with if (customer_id === 'acme') branches. You have abandoned your unified abstraction and are now maintaining custom software for every enterprise client.

The solution is not a bigger standard data model. The solution is building a declarative architecture for per-account API mappings. This requires three capabilities most integration infrastructures lack: dynamic field discovery, aggressive metadata caching that respects strict rate limits, and continuous monitoring for schema drift.

This guide covers exactly how to build all three so you can handle infinite enterprise schema variations without writing a single line of integration-specific code.

The Enterprise Integration Trap: Why Standard Data Models Fail

Unified APIs are designed to abstract away the differences between third-party systems. They force disparate data structures into a single, predictable schema. This is highly effective for standard data, but it fundamentally conflicts with how enterprises use software.

Enterprise systems like Salesforce, Jira, and Workday are not just applications; they are highly customized relational databases. Customers mutate these systems to fit their specific business processes. If your integration infrastructure cannot read and write to these mutated structures, your software cannot participate in their core workflows.

The moment you integrate with an enterprise CRM or ticketing system, you hit the wall of custom fields. Customer A has Industry_Vertical__c on their Account object. Customer B calls it Sector__c. Customer C has a completely custom object with 47 fields that don't exist anywhere else.

Attempting to handle this via code-level customizations fails for three reasons:

  1. Deployment bottlenecks: Adding a new custom field mapping requires a code change, a pull request, CI/CD pipelines, and a production deployment.
  2. Maintenance nightmares: When an API provider deprecates an endpoint, you have to update dozens of bespoke customer scripts.
  3. Opaque data structures: Custom fields rarely look like annual_revenue in the API response. In Jira, a custom field is referenced by customfield_ plus an internal ID, rather than a readable name. You get customfield_10472 in your API response with zero context about what it represents.

To solve this, you must move away from code and embrace configuration. But before you can map a custom field, your system must know it exists.

Step 1: Dynamic Custom Field Discovery

Custom field discovery is the process of querying a third-party API's metadata endpoints at runtime to map opaque internal identifiers to human-readable field names, data types, and validation rules.

Every major SaaS platform exposes some form of metadata API, but they all do it differently. To build a scalable discovery engine, you must abstract these differences:

Platform Metadata Endpoint What You Get
Salesforce GET /services/data/v59.0/sobjects/{Object}/describe Full field metadata: name, type, label, picklist values, relationships
Jira GET /rest/api/3/field/search Field ID, display name, schema type, custom field type
HubSpot GET /crm/v3/properties/{objectType} Property name, label, type, options, group
NetSuite SuiteQL: SELECT * FROM customfield Field ID, label, type, associated record types

The Opaque ID Problem

In the Jira REST API, custom fields are uniquely identified by the field ID, as display names are not unique within a Jira instance. For example, you could have two fields named "Escalation date", one with an ID of "12221" and one with an ID of "12222".

If you want to map customfield_10024 to your application's priority_level field, you cannot guess what it means based on a standard payload. You must query the provider's metadata endpoint to retrieve the dictionary.

Here's a practical example of what field discovery looks like against the Jira Cloud API:

# Fetch all fields (system + custom) for a Jira Cloud instance
curl -s -X GET \
  'https://your-instance.atlassian.net/rest/api/3/field/search?type=custom&maxResults=50' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'Accept: application/json'

The response gives you the mapping dictionary you need:

{
  "values": [
    {
      "id": "customfield_10024",
      "name": "Customer Priority",
      "schema": {
        "type": "string",
        "custom": "com.atlassian.jira.plugin.system.customfieldtypes:select"
      }
    },
    {
      "id": "customfield_10106",
      "name": "Story Points",
      "schema": {
        "type": "number",
        "custom": "com.atlassian.jira.plugin.system.customfieldtypes:float"
      }
    }
  ]
}

Salesforce takes a different approach. You use the sObject Describe resource to retrieve all the metadata for an object, including information about each field, URLs, and child relationships. A single Salesforce object can have up to 800 custom fields created in the org, plus up to 100 from managed packages, for a total ceiling of 900.

That is a massive amount of metadata to keep track of per customer.

Architecting the Discovery Workflow

A scalable custom field architecture requires a dedicated discovery service that runs asynchronously. When a new integrated account is connected, this service should immediately crawl the provider's metadata endpoints to build a localized dictionary for that specific tenant.

This dictionary powers your UI. When an enterprise customer configures their integration in your application, your frontend queries this dictionary to render a dropdown mapping interface. The customer selects "Customer Priority" from the dropdown, and your backend saves the mapping configuration as customfield_10024 -> priority_level.

The key decision is when to run discovery. You have three options:

  • At connection time: Run discovery once when the customer first connects. Fast, but stale within days.
  • On a schedule: Poll every N hours. Balances freshness against rate limit cost.
  • On demand with caching: Check the cache first, fall through to the API on miss. Best for high-volume integrations.

Most production systems need a combination: discover at connection time, cache aggressively, and re-discover on a schedule to catch drift. However, this discovery process introduces a severe operational risk: API rate limits.

Step 2: Caching Metadata to Survive API Rate Limits

API metadata caching is the practice of storing discovered field schemas in a distributed, low-latency datastore with a specific Time-To-Live (TTL) to prevent exhausting strict provider rate limits on schema endpoints.

Metadata endpoints are computationally expensive for third-party providers to serve, which means they are heavily rate-limited. You cannot call the metadata endpoint on every request. The math simply doesn't work.

For example, HubSpot's Associations API restricts callers to 110 requests every 10 seconds. Pipedrive's Search API enforces a strict limit of 4 requests per second. If you are syncing data for 200 customer accounts and each sync starts with a metadata fetch to resolve opaque IDs, you have burned 200 requests before touching a single record. At HubSpot's burst limit, that is nearly 20 seconds of rate budget spent on metadata alone.

If your application attempts to resolve opaque field IDs by calling the metadata endpoint during every real-time data sync, you will trigger HTTP 429 Too Many Requests errors almost instantly, bringing your entire integration pipeline down.

The Caching Strategy and TTLs

To survive these limits, you must decouple metadata retrieval from data synchronization.

sequenceDiagram
    participant App as Your Application
    participant Cache as Distributed Cache (KV)
    participant API as 3rd-Party Metadata API
    
    App->>Cache: Get schema for account_id
    alt Cache Hit (within TTL)
        Cache-->>App: Return schema dictionary
    else Cache Miss or Expired
        App->>API: Fetch metadata (/describe)
        API-->>App: Return raw metadata
        App->>Cache: Store with TTL + Jitter
        App-->>App: Build ID-to-name mapping
    end
    App->>App: Apply per-account field mapping

Not all metadata changes at the same rate. Your cache TTL should reflect this reality:

Metadata Type Recommended TTL Rationale
Field names and types 4-12 hours Admins change these occasionally, but rarely minute-to-minute.
Picklist/enum values 30-60 minutes These change more frequently (e.g., adding a new deal stage).
Object relationships 12-24 hours Rarely change once established.
Required field rules 1-2 hours Validation rules change during active admin sessions.

Pro-tip: Always add a random jitter (e.g., +/- 15 minutes) to your TTLs to prevent a "cache stampede" where thousands of accounts attempt to refresh their metadata at the exact same second.

Eviction Policies for Multi-Tenant Metadata

TTLs handle expiration, but they don't protect you from memory pressure. When you're caching field schemas for hundreds of enterprise accounts - each with potentially hundreds of custom fields - memory usage adds up fast.

The recommended approach is to combine TTL-based expiration with an LRU (Least Recently Used) eviction policy. This gives you two layers of protection:

  • TTL ensures stale metadata is automatically refreshed at the intervals from the table above.
  • LRU eviction handles memory pressure by dropping schemas for accounts that haven't been accessed recently. If a customer hasn't triggered a sync in 48 hours, their cached schema is a good candidate for eviction.

For most multi-tenant integration platforms, configure your cache store with a memory ceiling and an LRU eviction policy applied to all keys. This means any key - regardless of whether it has a TTL set - can be evicted if memory runs low, with the least recently accessed keys going first. Track your cache hit ratio as a health metric. If it drops below 85%, you either need more memory or your TTLs are too aggressive.

One subtlety: don't evict mid-sync. If a background sync job is actively processing records for an account, evicting that account's schema mid-flight forces an unplanned metadata fetch - exactly the kind of burst that triggers 429s. Pin actively-syncing account schemas in cache until the sync job completes.

Caching Metadata vs. Caching Customer Data

A common misconception is that metadata caching means you're storing customer records. It doesn't. This is a critical distinction for teams building real-time integrations.

Metadata caching stores the schema dictionary - field names, types, picklist values, and relationships. This is structural information about how data is organized, not the data itself. It changes infrequently (hours to days) and is safe to cache aggressively.

Customer data - actual records like contacts, deals, or tickets - flows through your system in real time and should not be cached by your integration layer. When a webhook fires or a sync job fetches records, the actual payload passes through your mapping engine and into your application's database without intermediate caching.

The pattern looks like this: your real-time data pipeline reads from the provider, resolves opaque field IDs against the cached metadata dictionary, applies the per-account field mapping, and writes the transformed record directly to your application. The metadata cache exists solely to avoid calling the provider's /describe endpoint on every single data request.

This means unified API platforms can handle real-time data without caching customer information. The cache holds schema structure, not business data. Your customers' records never sit in an intermediate cache layer - they flow through the mapping engine in real time, interpreted using the cached schema context.

Handling HTTP 429s When They Happen

Even with caching, you will occasionally hit rate limits during the initial discovery phase. Your system must handle this gracefully.

Info

Factual note on rate limits: Truto does not automatically retry, throttle, or apply backoff on rate limit errors. When an upstream API returns HTTP 429, Truto passes that error directly to the caller. Truto normalizes upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. The caller is strictly responsible for implementing their own retry and exponential backoff logic.

By leveraging these standardized rate limit headers, your background workers can parse the ratelimit-reset timestamp and pause the discovery queue until the exact moment the provider allows new requests.

The pattern you want for your own retry logic looks like this:

async function fetchWithBackoff(request: () => Promise<Response>, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await request();
 
    if (response.status !== 429) return response;
 
    // Use standard IETF headers if available
    const resetAt = response.headers.get('ratelimit-reset');
    const remaining = response.headers.get('ratelimit-remaining');
 
    const waitMs = resetAt
      ? (parseInt(resetAt) * 1000) - Date.now()
      : Math.pow(2, attempt) * 1000 + Math.random() * 500;
 
    await sleep(Math.max(waitMs, 1000));
  }
  throw new Error('Rate limit exceeded after max retries');
}

The ratelimit-reset header tells you exactly when you can retry, so you don't waste time guessing with exponential backoff. When that header isn't available, fall back to exponential backoff with jitter to prevent your IP from being temporarily banned by the provider's WAF.

Safe Schema Discovery at Scale

When you're operating across hundreds of integrated accounts and multiple providers, naive discovery becomes a denial-of-service attack against yourself. If 200 accounts all need metadata refreshed within the same hour, and each provider caps you at 100 requests per 10-second window, you need a discovery strategy that respects provider-level rate budgets.

Rate budgeting means allocating a fixed share of your available API calls to metadata discovery, keeping the rest for actual data operations. A good starting point:

Budget Allocation % of Rate Limit Purpose
Data sync operations 70-80% Fetching and writing actual records
Metadata discovery 15-20% Schema refreshes, field lookups
Headroom reserve 5-10% Burst capacity for retries

Stagger discovery across tenants. Instead of refreshing all accounts at the top of the hour, spread them evenly across the refresh interval. If your TTL is 4 hours and you have 200 accounts on Salesforce, schedule roughly 1 discovery request per 72 seconds. This turns a burst of 200 concurrent metadata requests into a steady trickle that stays well under the rate ceiling.

The impact is significant. Without staggering, those 200 accounts would fire at once, instantly exceeding a typical 100-requests-per-10-seconds limit and triggering a cascade of 429s. With staggered scheduling, you consume roughly 3 requests per 10-second window for discovery alone - leaving 97% of your rate budget for data operations.

Batch where providers support it. Some providers let you describe multiple objects in a single call. Salesforce's Composite API, for example, lets you batch up to 25 subrequests in one HTTP call. Instead of making 10 separate describe calls for 10 objects, batch them into a single composite request and cut your rate limit consumption by 90%.

Prioritize discovery by activity. Not every account needs its metadata refreshed at the same frequency. Accounts with active syncs running should get priority. Dormant accounts - ones that haven't triggered a sync in 7+ days - can be dropped to a longer refresh interval or skipped entirely until their next sync begins.

Per-Account Throttling and Circuit Breaker Design

In a multi-tenant integration platform, one misbehaving customer account can exhaust the provider's rate limit for your entire OAuth application. If Customer A's Salesforce org has 900 custom fields and triggers constant full-schema refreshes, they will burn through the shared API quota and starve every other customer connected to that same provider.

The fix is per-account throttling using a token bucket pattern. Each integrated account gets its own bucket of tokens, refilled at a rate proportional to the total provider rate limit divided by the number of active accounts. When an account's bucket is empty, requests for that account queue until tokens refill - but other accounts keep flowing.

A practical allocation model:

  • Base allocation: Divide the provider's rate limit evenly across active accounts. If HubSpot allows 110 requests per 10 seconds and you have 22 active accounts, each account gets a base of 5 requests per 10-second window.
  • Burst allowance: Let accounts temporarily exceed their base allocation by up to 2x, borrowing from a shared pool. This handles legitimate burst scenarios like initial discovery.
  • Priority tiers: Give paying enterprise customers a larger share of the rate budget than trial or free-tier accounts.

Circuit breakers add a second layer of protection. When a specific provider endpoint starts returning errors - whether 429s, 500s, or timeouts - a circuit breaker prevents your system from piling on more requests that will also fail.

The circuit breaker operates in three states:

  • Closed (normal): Requests flow through. The breaker tracks the error rate over a rolling window (e.g., last 60 seconds).
  • Open (tripped): When the error rate exceeds a threshold (e.g., 50% of requests failing), the breaker opens. All requests to that provider endpoint for that account immediately return a cached response or a structured error. No API calls are made.
  • Half-open (testing): After a cooldown period (e.g., 30 seconds), the breaker allows a single probe request through. If it succeeds, the breaker closes. If it fails, the breaker re-opens with a longer cooldown.
stateDiagram-v2
    [*] --> Closed
    Closed --> Open : Error rate exceeds<br>threshold (e.g. 50%)
    Open --> HalfOpen : Cooldown expires<br>(e.g. 30 seconds)
    HalfOpen --> Closed : Probe request<br>succeeds
    HalfOpen --> Open : Probe request<br>fails

Scope your circuit breakers per provider per account. A Salesforce outage affecting Customer A should not trip the breaker for Customer B's Salesforce instance, and it definitely should not affect HubSpot connections. This isolation prevents cascading failures across your tenant base.

Step 3: Monitoring and Alerting for Schema Drift

API schema drift occurs when a third-party API or a customer's internal administrator modifies a data structure—renaming fields, modifying types, adding or removing properties—without notifying connected applications.

Once you have discovered the custom fields and mapped them, you face the most dangerous phase of enterprise integrations: maintenance. Enterprise environments are highly fluid. A Salesforce admin will log in on a Tuesday and change a string custom field into a multi-select array because the sales team requested a new reporting feature. They will not tell you they did this.

The data proves how catastrophic this is. According to KushoAI's State of Agentic API Testing report, 41% of APIs experience undocumented schema changes within 30 days, climbing to 63% within 90 days. Furthermore, schema and validation errors account for 22% of all API failures—making it the second most common cause of integration failure right behind authentication issues (34%).

Unmonitored schema drift costs enterprises millions in silent failures. The average cost per schema drift incident is estimated at $35,000. The real danger isn't that things break loudly; it's that schema drift often fails silently. Your sync keeps running, but the Revenue_Forecast__c field your customer's CFO relies on is suddenly returning null because it was renamed to Rev_Forecast_v2__c.

Implementing Schema Drift Detection

To combat this, you need a two-pronged approach: scheduled metadata comparisons to detect drift early, and edge validation to prevent bad data from entering your system.

1. Scheduled Metadata Comparison (The Early Warning System)

The most effective approach compares a stored baseline schema against the current schema on every scheduled metadata refresh:

interface FieldSchema {
  id: string;
  name: string;
  type: string;
  required: boolean;
}
 
function detectDrift(
  baseline: FieldSchema[],
  current: FieldSchema[]
): { added: FieldSchema[]; removed: FieldSchema[]; typeChanged: FieldSchema[] } {
  const baseMap = new Map(baseline.map(f => [f.id, f]));
  const currMap = new Map(current.map(f => [f.id, f]));
 
  const added = current.filter(f => !baseMap.has(f.id));
  const removed = baseline.filter(f => !currMap.has(f.id));
  const typeChanged = current.filter(f => {
    const base = baseMap.get(f.id);
    return base && base.type !== f.type;
  });
 
  return { added, removed, typeChanged };
}

Severity tiers matter here:

  • Additive changes (new fields): Log and update the baseline. No action needed unless the field is expected by a mapping.
  • Subtractive changes (removed fields): Alert immediately. Any mapping referencing this field will fail.
  • Type mutations (e.g., string to array): Alert immediately. Downstream type coercion will produce garbage data.

2. JSON Schema Validation at the Edge (The Boundary Defense)

If you do not catch schema drift at the boundary, bad data will poison your application's database. When your discovery engine caches the metadata, it should compile it into a JSON Schema definition.

Every time a webhook or a sync job pulls a record from the third-party API, the payload must be validated against this schema before it is mapped.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "customfield_10024": {
      "type": "string"
    }
  }
}

If the Salesforce admin changes the field to an array, the validation will throw an error: Type mismatch for customfield_10024: expected string, got array.

What Production Monitoring Looks Like

flowchart TD
    A[Scheduled Metadata Refresh<br>every 1-4 hours] --> B{Compare Against<br>Stored Baseline}
    B -->|No Changes| C[Update last_checked timestamp]
    B -->|Additive Only| D[Update baseline<br>Log new fields]
    B -->|Breaking Change| E[Trigger Alert]
    E --> F[Route to Dead Letter Queue]
    E --> G[Notify customer success team]
    E --> H[Create mapping update task]

The important engineering decision: do you pause the sync or keep running with degraded data? For most enterprise use cases, halting the sync for that specific record and routing it to a Dead Letter Queue (DLQ) is better than silently writing corrupted data.

By catching the drift at the edge, you protect your application's data integrity and shift the troubleshooting narrative from "your integration is broken" to "your recent Salesforce change requires a mapping update."

Operational Monitoring and Alerting Recommendations

Schema drift detection only works if someone sees the alerts. Beyond the automated schema comparison described above, instrument your integration infrastructure with these operational metrics:

Rate limit health:

  • Track ratelimit-remaining values per provider per account on every API response. Alert when remaining budget drops below 20% of the window allocation.
  • Monitor the ratio of 429 responses to total requests. A healthy integration stays below 1% 429s. Anything above 5% means your throttling or caching strategy is broken.

Cache performance:

  • Measure cache hit ratio per provider. Target 90%+ for metadata lookups. A drop below 85% signals either TTLs that are too short or memory pressure causing premature evictions.
  • Track the age of cached schemas. If any account's metadata hasn't been refreshed in over 2x the configured TTL, something is wrong with your discovery scheduler.

Mapping health:

  • Count mapping errors per account - cases where a cached field mapping references a field ID that doesn't exist in the incoming payload. A spike means schema drift happened and your detection hasn't caught it yet.
  • Track null rates for mapped fields. If a field that historically returns data starts returning null for a specific account, it may have been renamed or had its permissions changed.

Circuit breaker state:

  • Log every state transition (closed → open, open → half-open, half-open → closed). If a breaker for a specific provider is tripping more than once per day, investigate the root cause rather than just relying on the backoff.
  • Alert on breakers that stay open for more than 10 minutes. This usually indicates a provider outage, not a transient error.

The goal is to shift from reactive debugging ("why did this sync fail?") to proactive detection ("this account's schema changed 4 hours ago and the mapping needs an update"). Build dashboards that give your customer success team visibility into mapping health per account, so they can proactively reach out before the customer notices a problem.

Moving from Code to Configuration: The Declarative Approach

Building the infrastructure for discovery, caching, and drift monitoring is a massive engineering undertaking. If you're integrating with 3-5 platforms and serving fewer than 50 customers, building it yourself is viable. At 10+ platforms and hundreds of enterprise accounts, each with unique schemas, the configuration-driven approach becomes nearly mandatory.

If you build this in-house, you will spend months writing boilerplate code instead of shipping core product features. This is why modern engineering teams are abandoning code-first integrations in favor of declarative architectures.

The 3-Level Override Hierarchy

Truto solves the custom field problem by moving all integration-specific logic out of your codebase and into configuration data. Truto utilizes a 3-level override hierarchy to handle per-account API mappings without code deployments:

  1. Platform Base: Truto provides a standardized unified schema that works out-of-the-box for standard fields across all providers.
  2. Environment Override: You can override the base mapping for your entire staging or production environment, adjusting how data translates for your specific application.
  3. Account Override: Individual connected accounts can have their own mapping overrides. If one enterprise customer requires 140 custom fields, their specific integrated account holds a configuration payload that maps those fields, affecting no other customer.

These mappings are written in JSONata, a powerful, Turing-complete expression language purpose-built for reshaping JSON objects, enabling per-customer data model customization without code. A complex transformation that handles dynamic typing and array manipulation is stored as a single JSONata expression in the database, not as a conditional branch in application code.

Automated Discovery via the Fields Resource

Instead of forcing developers to write custom scripts to hit provider metadata endpoints, Truto's Unified API exposes a standardized Fields resource.

# Discover custom fields for any connected CRM account
GET /unified/crm/fields?integrated_account_id=abc123

When you query this endpoint, Truto automatically handles the underlying provider complexity—whether that means calling Salesforce's Describe API, HubSpot's Properties API, or Jira's Field API. It handles the pagination, normalizes the response, and returns a clean, standardized list of every standard and custom field available for that specific customer account. This allows your frontend team to build dynamic mapping UIs in hours, not weeks.

AI-Ready Custom Fields via MCP

For teams building AI agents, custom fields present a unique challenge: LLMs cannot guess opaque field IDs. Truto's architecture natively solves this. Because integration behavior is entirely data-driven, Truto automatically generates Model Context Protocol (MCP) tool definitions from the configuration.

When you generate an MCP server for an integrated account, Truto automatically injects the discovered custom fields into the tool's JSON Schema. The LLM instantly understands the customer's bespoke data model, allowing it to read and write to custom objects without manual prompting or hardcoded context injection.

The Playbook: What to Implement and When

Here is a prioritized implementation order for teams adding per-account API mapping support:

Week 1-2: Foundation

  • Implement metadata discovery for your top 2-3 integrations.
  • Build a cache layer with per-metadata-type TTLs.
  • Store field mappings as configuration data, not code.

Week 3-4: Resilience

  • Add schema drift detection on scheduled metadata refreshes.
  • Implement severity-based alerting (additive vs. breaking changes).
  • Build a customer-facing field mapping UI that reads from your discovery cache.

Week 5+: Scale

  • Evaluate whether a declarative mapping platform eliminates your maintenance burden.
  • Add per-account mapping overrides so enterprise customers can self-serve.
  • Instrument monitoring for mapping errors, not just API errors.

Handling enterprise custom fields does not have to be a technical debt sentence. The companies that get this right stop losing enterprise deals over custom fields. The ones that don't keep telling prospects "we only support standard fields" and watch them walk to a competitor who doesn't.

FAQ

What is dynamic custom field discovery?
It is the process of querying a third-party API's metadata endpoint at runtime to map opaque internal identifiers (like `customfield_10024`) to human-readable field names, data types, and validation rules.
How do you handle API rate limits when fetching metadata?
Metadata must be aggressively cached using a TTL strategy based on the data type. When rate limits are hit, systems should rely on standard IETF rate-limit headers (like `ratelimit-reset`) to implement precise exponential backoff rather than retrying blindly.
What is API schema drift and why does it matter?
Schema drift occurs when a third-party API or a customer's admin modifies a data structure (e.g., renaming a field or changing a string to an array) without notifying connected apps. It affects 41% of APIs within 30 days and causes silent data corruption that costs enterprises an average of $35,000 per incident.
What are per-account API mappings?
Per-account API mappings are customer-specific configurations that translate between your application's data model and each customer's unique third-party API schema. They let you handle bespoke custom fields differently for each enterprise client without writing integration-specific code.

More from our Blog