Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Configuration settings that determine runtime behavior.
Pagination settings
| Property | Default | Description | 
|---|---|---|
| runtime.pagination.max-page-size | Defines maximum records per page | |
| runtime.pagination.default-page-size | Sets default records per response | 
REST settings
| Property | Default | Description | 
|---|---|---|
| runtime.rest.path | "/api" | Base path for REST endpoints | 
| runtime.rest.enabled | true | Allows enabling or disabling REST requests for all entities | 
| runtime.rest.request-body-strict | true | Disallows extraneous fields in request body when true | 
GraphQL settings
| Property | Default | Description | 
|---|---|---|
| runtime.graphql.allow-introspection | true | Allows querying of underlying GraphQL schema | 
| runtime.graphql.path | "/graphql" | Base path for the GraphQL endpoint | 
| runtime.graphql.enabled | true | Allows enabling or disabling GraphQL requests for all entities | 
| runtime.graphql.depth-limit | null | Maximum allowed depth of a GraphQL query | 
| runtime.graphql.multiple-mutations.create.enabled | false | Allows multiple-create mutations for all entities | 
Host settings
| Property | Default | Description | 
|---|---|---|
| runtime.host.max-response-size-mb | 100 | Maximum size (MB) of database response allowed in a single result | 
| runtime.host.mode | "production" | Running mode; "production"or"development" | 
CORS settings
| Property | Default | Description | 
|---|---|---|
| runtime.host.cors.origins | [] | Allowed CORS origins | 
| runtime.host.cors.allow-credentials | false | Sets value for Access-Control-Allow-Credentials header | 
Authentication settings
| Property | Default | Description | 
|---|---|---|
| runtime.host.authentication.provider | null | Authentication provider | 
| runtime.host.authentication.jwt.audience | null | JWT audience | 
| runtime.host.authentication.jwt.issuer | null | JWT issuer | 
Cache settings
| Property | Default | Description | 
|---|---|---|
| runtime.cache.enabled | false | Enables caching of responses globally | 
| runtime.cache.ttl-seconds | 5 | Time to live (seconds) for global cache | 
Telemetry settings
| Property | Default | Description | 
|---|---|---|
| runtime.telemetry.application-insights.connection-string | null | Application Insights connection string | 
| runtime.telemetry.application-insights.enabled | false | Enables or disables Application Insights telemetry | 
| runtime.telemetry.open-telemetry.endpoint | null | OpenTelemetry collector URL | 
| runtime.telemetry.open-telemetry.headers | {} | OpenTelemetry export headers | 
| runtime.telemetry.open-telemetry.service-name | "dab" | OpenTelemetry service name | 
| runtime.telemetry.open-telemetry.exporter-protocol | "grpc" | OpenTelemetry protocol ("grpc" or "httpprotobuf") | 
| runtime.telemetry.open-telemetry.enabled | true | Enables or disables OpenTelemetry | 
| runtime.telemetry.log-level.namespace | null | Namespace-specific log level override | 
| runtime.health.enabled | true | Enables or disables the health check endpoint globally | 
| runtime.health.roles | null | Allowed roles for the comprehensive health endpoint | 
| runtime.health.cache-ttl-seconds | 30 | Time to live (seconds) for the health check report cache entry | 
Format overview
{
  "runtime": {
    "pagination": {
      "max-page-size": <integer|null> (default: `100000`),
      "default-page-size": <integer|null> (default: `100`)
    },
    "rest": {
      "path": <string> (default: "/api"),
      "enabled": <true>|<false>,
      "request-body-strict": <true>|<false> (default: `true`)
    },
    "graphql": {
      "path": <string> (default: "/graphql"),
      "enabled": <true>|<false>,
      "allow-introspection": <true>|<false>,
      "depth-limit": <integer|null> (default: `null`),
      "multiple-mutations": {
        "create": {
          "enabled": <true>|<false> (default: `false`)
        }
      }
    },
    "host": {
      "mode": <"production"> (default) | <"development">,
      "max-response-size-mb": <integer|null> (default: `158`),
      "cors": {
        "origins": [ "<string>" ],
        "allow-credentials": <true>|<false> (default: `false`)
      },
      "authentication": {
        "provider": <string> (default: "AppService"),
        "jwt": {
          "audience": "<string>",
          "issuer": "<string>"
        }
      }
    }
  },
  "cache": {
    "enabled": <true>|<false> (default: `false`),
    "ttl-seconds": <integer> (default: `5`)
  },
  "telemetry": {
    "application-insights": {
      "connection-string": "<string>",
      "enabled": <true>|<false> (default: `true`)
    },
    "open-telemetry": {
      "endpoint": "<string>",
      "headers": "<string>",
      "service-name": <string> (default: "dab"),
      "exporter-protocol": <"grpc"> (default) | <"httpprotobuf">,
      "enabled": <true>|<false> (default: `true`)
    },
    "log-level": {
      // namespace keys
      "<namespace>": <"trace"|"debug"|"information"|"warning"|"error"|"critical"|"none"|null>
    }
  },
  "health": {
    "enabled": <true>|<false> (default: `true`),
    "roles": [ "<string>" ],
    "cache-ttl-seconds": <integer> (default: `5`)
  }
}
Mode (Host runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | host | enum ( production|development) | ❌ No | production | 
Development behavior
- Enabled Nitro (formerly Banana Cake Pop) for GraphQL testing
- Enabled Swagger UI for REST testing
- Enabled anonymous health checks
- Increased logging verbosity (Debug)
Format
{
  "runtime": {
    "host": {
      "mode": "production" (default) | "development"
    }
  }
}
Maximum response size (Host runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host | max-response-size-mb | integer | ❌ No | 158 | 
Sets the maximum size (in megabytes) for any given result. As large responses can strain the system, max-response-size-mb caps the total size (different from row count) to prevent overload, which is especially with large columns like text or JSON.
| Value | Result | 
|---|---|
| not set | Use default | 
| null | Use default | 
| integer | Any positive 32-bit integer | 
| <= 0 | Not supported | 
Format
{
  "runtime": {
    "host": {
      "max-response-size-mb": <integer; default: 158>
    }
  }
}
GraphQL (runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | graphql | object | ❌ No | - | 
Global GraphQL configuration.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.graphql | enabled | boolean | ❌ No | None | 
| runtime.graphql | path | string | ❌ No | "/graphql" | 
| runtime.graphql | depth-limit | integer | ❌ No | None (unlimited) | 
| runtime.graphql | allow-introspection | boolean | ❌ No | True | 
| runtime.graphql | multiple-mutations.create.enabled | boolean | ❌ No | False | 
Property notes
- Sub-paths are not allowed for the pathproperty.
- Use depth-limitto constrain nested queries.
- Set allow-introspectiontofalseto hide the GraphQL schema.
- Use multiple-mutationsto insert multiple entities in a single mutation.
Format
{
  "runtime": {
    "graphql": {
      "enabled": <true> (default) | <false>
      "depth-limit": <integer|null> (default: `null`),
      "path": <string> (default: /graphql),
      "allow-introspection": <true> (default) | <false>,
      "multiple-mutations": {
        "create": {
          "enabled": <true> (default) | <false>
        }
    }
  }
}
Example: multiple mutations
Configuration
{
  "runtime": {
    "graphql": {
      "multiple-mutations": {
        "create": {
          "enabled": true
        }
      }
    }
  },
  "entities": {
    "User": {
      "source": "dbo.Users",
      "permissions": [
        {
          "role": "anonymous",
          "actions": ["create"] // entity permissions are required
        }
      ]
    }
  }
}
GraphQL mutation
mutation {
  createUsers(input: [
    { name: "Alice", age: 30, isAdmin: true },
    { name: "Bob", age: 25, isAdmin: false },
    { name: "Charlie", age: 35, isAdmin: true }
  ]) {
    id
    name
    age
    isAdmin
  }
}
REST (runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | rest | object | ❌ No | - | 
Global REST configuration.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.rest | enabled | boolean | ❌ No | None | 
| runtime.rest | path | string | ❌ No | "/api" | 
| runtime.rest | request-body-strict | boolean | ❌ No | True | 
Property notes
- If global enabledisfalse, individual entity-levelenableddoesn't matter.
- The pathproperty doesn't support subpath values like/api/data.
- request-body-strictwas introduced to help simplify .NET POCO objects.
| request-body-strict | Behavior | 
|---|---|
| true | Extra fields in the request body cause a BadRequestexception. | 
| false | Extra fields in the request body are ignored. | 
Format
{
  "runtime": {
    "rest": {
      "enabled": <true> (default) | <false>,
      "path": <string> (default: /api),
      "request-body-strict": <true> (default) | <false>
    }
  }
}
Note
When deploying Data API builder using Static Web Apps (preview), the Azure service automatically injects another subpath /data-api to the url. This behavior ensures compatibility with existing Static Web App features. The resulting endpoint would be /data-api/api/<entity>. This note is only relevant to Static Web Apps.
Example: request-body-strict
- Columns with a default()value are ignored duringINSERTonly when their value in the payload isnull. As a consequence,INSERToperations intodefault()columns, whenrequest-body-strictistrue, can't result in explicitnullvalues. To accomplish this, anUPDATEoperation is required.
- Columns with a default()aren't ignored duringUPDATEregardless of payload value.
- Computed columns are always ignored.
- Autogenerated columns are always ignored.
Sample table
CREATE TABLE Users (
    Id INT PRIMARY KEY IDENTITY, -- auto-generated column
    Name NVARCHAR(50) NOT NULL,
    Age INT DEFAULT 18, -- column with default
    IsAdmin BIT DEFAULT 0, -- column with default
    IsMinor AS IIF(Age <= 18, 1, 0) -- computed column
);
Request payload
{
  "Id": 999,
  "Name": "Alice",
  "Age": null,
  "IsAdmin": null,
  "IsMinor": false,
  "ExtraField": "ignored"
}
Insert behavior when request-body-strict = false
INSERT INTO Users (Name) VALUES ('Alice');
-- Default values for Age (18) and IsAdmin (0) are applied by the database.
-- IsMinor is ignored because it’s a computed column.
-- ExtraField is ignored.
-- The database generates the Id value.
Response payload
{
  "Id": 1,          // Auto-generated by the database
  "Name": "Alice",
  "Age": 18,        // Default applied
  "IsAdmin": false, // Default applied
  "IsMinor": true   // Computed
}
Update behavior when request-body-strict = false
UPDATE Users
SET Name = 'Alice Updated', Age = NULL
WHERE Id = 1;
-- IsMinor and ExtraField are ignored.
Response payload
{
  "Id": 1,
  "Name": "Alice Updated",
  "Age": null,
  "IsAdmin": false,
  "IsMinor": false // Recomputed by the database (false when age is `null`)
}
CORS (host runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host | cors | object | ❌ No | - | 
Global CORS configuration.
Tip
CORS stands for "Cross-Origin Resource Sharing." It is a browser security feature controlling whether web pages can make requests to a different domain than the one that served them.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host.cors | allow-credentials | boolean | ❌ No | False | 
| runtime.host.cors | origins | string array | ❌ No | None | 
Note
The allow-credentials property sets the Access-Control-Allow-Credentials CORS header.
Format
{
  "runtime": {
    "host": {
      "cors": {
        "allow-credentials": <true> (default) | <false>,
        "origins": ["<array-of-strings>"]
      }
    }
  }
}
Note
The wildcard * is valid as a value for origins.
Provider (Authentication host runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host.authentication | provider | enum ( AppService|EntraId|Custom|Simulator) | ❌ No | AppService | 
Defines the method of authentication used by the Data API builder.
Anonymous-only (auth provider)
{
 "host": {
    // omit the authentication section
 }
}
When the entire authentication section is omitted from the dab-config.json file, no authentication provider is used. In this case, Data API builder operates in a "no-auth" mode. In this mode, DAB doesn't look for any tokens or Authorization headers. The X-MS-API-ROLE header is also ignored in this configuration.
[!Note] Every request that comes into the engine is automatically and immediately assigned the system role of
anonymous. Access control is then exclusively handled by the permissions you define on each entity.
An example of entity permissions.
{
  "entities": {
    "Book": {
      "source": "dbo.books",
      "permissions": [
        {
          "role": "anonymous",
          "actions": [ "read" ]
        }
      ]
    }
  }
}
In this example, since no authentication provider is configured, all incoming requests are automatically considered to be from an anonymous user. The permissions array for the Book entity explicitly grants the anonymous role the ability to perform read operations. Any attempt to perform other actions (like create, update, delete) or access other entities not configured for anonymous access is denied.
StaticWebApps (auth provider) [deprecated]
{
 "host": {
  "authentication": {
   "provider": "StaticWebApps"
  }
 }
}
This provider is deprecated because the Static Web Apps preview feature Data Connections was retired in November 2025. While it remains functional, it was designed for a legacy implementation of authentication in Azure Static Web Apps. Developers should migrate to the AppService provider for better long-term support and consistency with Azure's broader "Easy Auth" platform.
[!Note] Migrating isn't as simple as changing the provider name in the configuration file. The
StaticWebAppsandAppServiceproviders expect different JSON structures within thex-ms-client-principalheader for processing roles.
AppService (auth provider)
{
 "host": {
  "authentication": {
   "provider": "AppService"
  }
 }
}
This provider is for applications hosted on Azure App Service, such as Azure Container Apps. The Azure hosting environment handles authentication and then passes the user's identity information to the application via request headers. It's intended for developers who want a simple, out-of-the-box authentication solution managed by the Azure platform.
This provider doesn't use a JWT token from the Authorization header. It relies on a special header, X-MS-CLIENT-PRINCIPAL, injected by the App Service platform. This header contains a base64-encoded JSON object with the user's identity details.
Anonymous: If the AppService provider is configured but a request arrives without the X-MS-CLIENT-PRINCIPAL header, the request is assigned to the system role of anonymous.
The decoded JSON from the X-MS-CLIENT-PRINCIPAL header typically looks like this:
{
  "auth_typ": "aad",
  "claims": [
    {"typ": "roles", "val": "admin"},
    {"typ": "roles", "val": "contributor"}
  ],
  "name_typ": "...",
  "role_typ": "..."
}
The roles are contained within the claims array.
About the X-MS-API-ROLE header
- Role and Behavior: The X-MS-API-ROLEheader is used to specify which role the user wants to assume for the current request. The value of this header must match one of the role values found in theclaimsarray of theX-MS-CLIENT-PRINCIPALobject.
- Is it required?: No. If the X-MS-API-ROLEheader is absent, the request is processed in the context of theauthenticatedsystem role. This means the user is recognized as logged in, but not as any specific application-defined role from the token.
- Behavior on Match: If the X-MS-API-ROLEheader is provided and its value matches a role in the client principal'sclaims, the user assumes that role for the request.
- Behavior on Mismatch: If the X-MS-API-ROLEheader is provided but the value doesn't match any role in the client principal, the request is rejected with a403 Forbiddenstatus code. This ensures a user can't claim a role they haven't been assigned.
EntraId (auth provider)
{
 "host": {
  "authentication": {
   "provider": "EntraId", // previously AzureAd
   "jwt": {
    "audience": "00001111-aaaa-2222-bbbb-3333cccc4444",
    "issuer": "https://login.microsoftonline.com/98765f43-21ba-400c-a5de-1f2a3d4e5f6a/v2.0"
   }
  }
 }
}
This provider secures endpoints with user and application identities in Microsoft Entra. It's ideal for any service where users or other services need secure access within the Entra tenant.
[!NOTE] The
EntraIdprovider was previously namedAzureAd. The old name still works, but developers are encouraged to migrate their configurations fromAzureAdtoEntraId.
This provider expects a standard JWT Bearer token in the Authorization header, issued by Microsoft Entra. The token must be configured for the specific application (using the audience claim). The roles for the user or service principal are expected to be in a claim within the token. The code looks for a roles claim by default.
Anonymous: If the EntraId provider is configured but a request arrives without the Authorization header, the request is assigned to the system role of anonymous.
A decoded JWT payload might look like this:
{
  "aud": "...", // Audience - your API
  "iss": "https://login.microsoftonline.com/{tenant-id}/v2.0", // Issuer
  "oid": "...", // User or principal object ID
  "roles": [
    "reader",
    "writer"
  ],
  // ... other claims
}
About the X-MS-API-ROLE header
- Role and Behavior: The X-MS-API-ROLEheader is used to specify a role the user wishes to assume for the request. The value of this header must match one of the role values found in therolesclaim of the JWT token.
- Is it required?: No. If the X-MS-API-ROLEheader is absent, the request is processed in the context of theauthenticatedsystem role. This means the user is recognized as logged in, but not as any specific application-defined role from the token.
- Behavior on Match: If the X-MS-API-ROLEheader is provided and it matches a role in therolesclaim, the user's context is set to that role.
- Behavior on Mismatch: If the X-MS-API-ROLEheader is provided but its value doesn't match any role in therolesclaim, the request is rejected with a403 Forbiddenstatus code. This ensures a user can't claim a role they haven't been assigned.
Custom (auth provider)
{
 "host": {
  "authentication": {
   "provider": "Custom",
   "jwt": {
    "audience": "<client-id-or-api-audience>",
    "issuer": "https://<your-domain>/oauth2/default"
   }
  }
 }
}
This provider is for developers who want to integrate Data API builder with a third-party identity provider (like Auth0, Okta, or a custom identity server) that issues JWTs. It provides the flexibility to configure the expected audience and issuer of the tokens.
The Custom provider expects a standard JWT Bearer token in the Authorization header. The key difference from the EntraId provider is that you configure the valid issuer and audience in the Data API builder's configuration file. The provider validates the token by checking that the trusted authority issued it. The user's roles are expected to be in a roles claim within the JWT payload.
[!NOTE] In some cases, depending on the third-party identity provider, developers need to coerce the structure of their JWT to match the structure expected by Data API builder (shown below).
Anonymous: If the Custom provider is configured but a request arrives without the Authorization header, the request is assigned to the system role of anonymous.
A decoded JWT payload for a custom provider might look like this:
{
  "aud": "my-api-audience", // Must match configuration
  "iss": "https://my-custom-issuer.com/", // Must match configuration
  "sub": "user-id",
  "roles": [
    "editor",
    "viewer"
  ],
  // ... other claims
}
About the X-MS-API-ROLE header
- Role and Behavior: The X-MS-API-ROLEheader functions exactly like it does with theEntraIdprovider. It allows the user to select one of their assigned roles. The value of this header must match one of the roles from therolesclaim in the custom JWT token.
- Is it required?: No. If the X-MS-API-ROLEheader is absent, the user is treated as being in theauthenticatedsystem role.
- Behavior on Match: If the X-MS-API-ROLEheader's value matches a role in the JWT'srolesclaim, the user's context is set to that role for authorization purposes.
- Behavior on Mismatch: If the X-MS-API-ROLEheader's value doesn't match any role in therolesclaim, the request is rejected with a403 Forbiddenstatus code. This ensures a user can't claim a role they haven't been assigned.
Simulator (auth provider)
This provider is designed to make it easy for developers to test their configuration, especially authorization policies, without needing to set up a full authentication provider like Entra Identity or EasyAuth. It simulates an authenticated user.
The Simulator provider doesn't use JWT tokens. Authentication is simulated. When using this provider, all requests are treated as if they're coming from an authenticated user.
About the X-MS-API-ROLE header
- Role and Behavior: The X-MS-API-ROLEheader is the only way to specify a role when using theSimulator. Since there's no token with a list of roles, the system implicitly trusts the role sent in this header.
- Is it required?: No.
- Behavior on Absence: If the X-MS-API-ROLEheader is absent, the request is processed in the context of theauthenticatedsystem role.
- Behavior on Presence: If the X-MS-API-ROLEheader is present, the request is processed in the context of the role specified in the header's value. There's no validation against a claims list, so the developer can simulate any role they need to test their policies.
Simulator in Production
If the authentication.provider is set to Simulator while the runtime.host.mode is production, Data API builder will fail to start.
"host": {
  "mode": "production", // or "development"
  "authentication": {
    "provider": "Simulator" 
  }
}
JWT (Authentication host runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host.authentication | jwt | object | ❌ No | - | 
Global JSON Web Token (JWT) configuration.

Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.host.authentication.jwt | audience | string | ❌ No | None | 
| runtime.host.authentication.jwt | issuer | string | ❌ No | None | 
Format
{
  "runtime": {
    "host": {
      "authentication": {
        "jwt": {
          "audience": "<client-id>",
          "issuer": "<issuer-url>"
        }
      }
    }
  }
}
Pagination (Runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | pagination | object | ❌ No | - | 
Global pagination limits for REST and GraphQL endpoints.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.pagination | max-page-size | int | ❌ No | 100,000 | 
| runtime.pagination | default-page-size | int | ❌ No | 100 | 
Max-page-size supported values
| Value | Result | 
|---|---|
| integer | Any positive 32-bit integer is supported. | 
| 0 | Not supported. | 
| -1 | Defaults to the maximum supported value. | 
| < -1 | Not supported. | 
Default-page-size supported values
| Value | Result | 
|---|---|
| integer | Any positive integer less than the current max-page-size. | 
| 0 | Not supported. | 
| -1 | Defaults to the current max-page-sizesetting. | 
| < -1 | Not supported. | 
Format
{
  "runtime": {
    "pagination": {
      "max-page-size": <integer; default: 100000>,
      "default-page-size": <integer; default: 100>
    }
  }
}
Note
When the value is greater than max-page-size, the results are capped at max-page-size.
Example: Paging in REST
Request
GET https://localhost:5001/api/users
Response payload
{
  "value": [
    {
      "Id": 1,
      "Name": "Alice",
      "Age": 30,
      "IsAdmin": true,
      "IsMinor": false
    },
    {
      "Id": 2,
      "Name": "Bob",
      "Age": 17,
      "IsAdmin": false,
      "IsMinor": true
    }
  ],
  "nextLink": "https://localhost:5001/api/users?$after=W3siRW50aXR5TmFtZSI6InVzZXJzIiwiRmllbGROYW1lI=="
}
Request Next Page
GET https://localhost:5001/api/users?$after=W3siRW50aXR5TmFtZSI6InVzZXJzIiwiRmllbGROYW1lI==
Example: Paging in GraphQL
Request payload (Query)
query {
  users {
    items {
      Id
      Name
      Age
      IsAdmin
      IsMinor
    }
    hasNextPage
    endCursor
  }
}
Response payload
{
  "data": {
    "users": {
      "items": [
        {
          "Id": 1,
          "Name": "Alice",
          "Age": 30,
          "IsAdmin": true,
          "IsMinor": false
        },
        {
          "Id": 2,
          "Name": "Bob",
          "Age": 17,
          "IsAdmin": false,
          "IsMinor": true
        }
      ],
      "hasNextPage": true,
      "endCursor": "W3siRW50aXR5TmFtZSI6InVzZXJzIiwiRmllbGROYW1lI=="
    }
  }
}
Request Next Page
query {
  users(after: "W3siRW50aXR5TmFtZSI6InVzZXJzIiwiRmllbGROYW1lI==") {
    items {
      Id
      Name
      Age
      IsAdmin
      IsMinor
    }
    hasNextPage
    endCursor
  }
}
Example: Accessing max-page-size in Requests
Use the max-page-size value by setting $limit (REST) or first (GraphQL) to -1.
REST
GET https://localhost:5001/api/users?$limit=-1
GraphQL
query {
  users(first: -1) {
    items {
      ...
    }
  }
}
Cache (runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | cache | object | ❌ No | - | 
Global Cache configuration.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.cache | enabled | boolean | ❌ No | False | 
| runtime.cache | ttl-seconds | integer | ❌ No | 5 | 
Tip
The entity-level cache.ttl-seconds property defaults to this global value.
Format
{
  "runtime": {
    "cache":  {
      "enabled": <boolean>,
      "ttl-seconds": <integer>
    }
  }
}
Important
If global enabled is false, individual entity-level enabled doesn't matter.
Telemetry (runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | telemetry | object | ❌ No | - | 
Global telemetry configuration.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.telemetry | log-level | dictionary | ❌ No | None | 
| runtime.telemetry | application-insights | object | ❌ No | - | 
| runtime.telemetry | open-telemetry | object | ❌ No | - | 
Configures logging verbosity per namespace. This follows standard .NET logging conventions and allows granular control, though it assumes some familiarity with Data API builder internals. Data API builder is open source: https://aka.ms/dab
Format
{
  "runtime": {
    "telemetry": {
      "log-level": {
        "namespace": "log-level",
        "namespace": "log-level"
      }
    }
  }
}
Tip
log-level can be hot-reloaded in both development and production. It's currently the only property that supports hot reload in production.
Example
{
  "runtime": {
    "telemetry": {
      "log-level": {
        "Azure.DataApiBuilder.Core.Configurations.RuntimeConfigValidator": "debug",
        "Azure.DataApiBuilder.Core": "information",
        "default": "warning"
      }
    }
  }
}
Application Insights (telemetry)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.telemetry | application-insights | object | ❌ No | - | 
Configures logging to Application Insights.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.telemetry.application-insights | enabled | boolean | ❌ No | False | 
| runtime.telemetry.application-insights | connection-string | string | ✔️ Yes | None | 
Format
{
  "runtime": {
    "telemetry": {
      "application-insights": {
        "enabled": <true; default: true> | <false>
        "connection-string": <string>
      }
    }
  }
}
OpenTelemetry (telemetry)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.telemetry | open-telemetry | object | ❌ No | - | 
Configures logging to Open Telemetry.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.telemetry.open-telemetry | enabled | boolean | ❌ No | true | 
| runtime.telemetry.open-telemetry | endpoint | string | ✔️ Yes | None | 
| runtime.telemetry.open-telemetry | headers | string | ❌ No | None | 
| runtime.telemetry.open-telemetry | service-name | string | ❌ No | "dab" | 
| runtime.telemetry.open-telemetry | exporter-protocol | enum ( grpc|httpprotobuf) | ❌ No | grpc | 
Multiple headers are , (comma) separated.
Format
{
  "runtime": {
    "telemetry": {
      "open-telemetry": {
        "enabled": <true> (default) | <false>,
        "endpoint": <string>,
        "headers": <string>,
        "service-name": <string> (default: "dab"),
        "exporter-protocol": <"grpc" (default) | "httpprotobuf">
      }
    }
  }
}
Example
{
  "runtime": {
    "telemetry": {
      "open-telemetry": {
        "enabled": true,
        // a gRPC endpoint example
        "endpoint": "http://localhost:4317",
        // an HTTP/protobuf endpoint example
        "endpoint": "http://localhost:4318/v1/metrics",
        "headers": "api-key=key,other-config-value=value",
        "service-name": "dab",
      }
    }
  }
}
Learn more about OTEL_EXPORTER_OTLP_HEADERS.
Note
gRPC (4317) is faster and supports streaming but requires more setup. HTTP/protobuf (4318) is simpler and easier to debug but less efficient.
Health (runtime)
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime | health | object | ❌ No | - | 
Global health check endpoint (/health) configuration.
Nested properties
| Parent | Property | Type | Required | Default | 
|---|---|---|---|---|
| runtime.health | enabled | boolean | ❌ No | true | 
| runtime.health | roles | string array | ✔️ Yes | None | 
| runtime.health | cache-ttl-seconds | integer | ❌ No | 5 | 
Behavior in development vs. production
| Condition | Development Behavior | Production Behavior | 
|---|---|---|
| health.enabled= false | 403status | 403status | 
| health.enabled= true | Depends on role | Depends on role | 
| rolesomitted ornull | Health displayed | 403status | 
| current role not in roles | 403status | 403status | 
| current role in roles | Health displayed | Health displayed | 
| rolesincludesanonymous | Health displayed | Health displayed | 
Format
{
  "health": {
    "enabled": <true> (default) | <false>,
    "roles": [ <string> ], // required in production
    "cache-ttl-seconds": <integer>
  }
}
Note
If global enabled is false, individual entity-level enabled doesn't matter.
Example
{
  "health": {
    "enabled": true,
    "roles": ["admin", "support"],
    "cache-ttl-seconds": 10
  }
}