| title | Configuration schema - Runtime section |
|---|---|
| description | The Data API Builder configuration file's runtime section with details for each property. |
| author | jerrynixon |
| ms.author | jnixon |
| ms.reviewer | sidandrews |
| ms.service | data-api-builder |
| ms.topic | reference |
| ms.date | 06/06/2025 |
| show_latex | true |
Configuration settings that determine runtime behavior.
| Property | Default | Description |
|---|---|---|
| runtime.pagination.max-page-size | Defines maximum records per page | |
| runtime.pagination.default-page-size | Sets default records per response |
| 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 |
| 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 |
| Property | Default | Description |
|---|---|---|
| runtime.host.max-response-size-mb | 158 |
Maximum size (MB) of database response allowed in a single result |
| runtime.host.mode | "production" |
Running mode; "production" or "development" |
| Property | Default | Description |
|---|---|---|
| runtime.host.cors.origins | [] |
Allowed CORS origins |
| runtime.host.cors.allow-credentials | false |
Sets value for Access-Control-Allow-Credentials header |
| 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 |
| Property | Default | Description |
|---|---|---|
| runtime.cache.enabled | false |
Enables caching of responses globally |
| runtime.cache.ttl-seconds | 5 |
Time to live (seconds) for global cache |
| 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 | 5 |
Time to live (seconds) for the health check report cache entry |
| runtime.health.max-query-parallelism | 4 |
Maximum concurrent health check queries (range: 1-8) |
{
"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`),
"max-query-parallelism": <integer> (default: `4`)
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
host |
enum (production | development) |
❌ No | production |
- Enabled Nitro (formerly Banana Cake Pop) for GraphQL testing
- Enabled Swagger UI for REST testing
- Enabled anonymous health checks
- Increased logging verbosity (Debug)
{
"runtime": {
"host": {
"mode": "production" (default) | "development"
}
}
}| 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 |
{
"runtime": {
"host": {
"max-response-size-mb": <integer; default: 158>
}
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
graphql |
object | ❌ No | - |
Global GraphQL configuration.
| 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 |
- Subpaths aren't 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.
{
"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>
}
}
}
}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
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
rest |
object | ❌ No | - |
Global REST configuration.
| 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 |
- 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 BadRequest exception. |
false |
Extra fields in the request body are ignored. |
{
"runtime": {
"rest": {
"enabled": <true> (default) | <false>,
"path": <string> (default: /api),
"request-body-strict": <true> (default) | <false>
}
}
}- 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 behavior, 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 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 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`)
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.host |
cors |
object | ❌ No | - |
Global CORS configuration.
Tip
CORS stands for "Cross-Origin Resource Sharing." It's a browser security feature that controls whether web pages can make requests to a different domain than the one that served them.
| 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.
{
"runtime": {
"host": {
"cors": {
"allow-credentials": <true> (default) | <false>,
"origins": ["<array-of-strings>"]
}
}
}
}Note
The wildcard * is valid as a value for origins.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.host.authentication |
provider |
enum (AppService | EntraId | Custom | Simulator) |
❌ No | None |
Selects the authentication method. Each provider validates identity differently. For step-by-step setup, see the how-to guides linked below.
| Provider | Use case | Identity source | How-to guide |
|---|---|---|---|
| (omitted) | Anonymous-only access | None | — |
AppService |
Azure-hosted apps (EasyAuth) | X-MS-CLIENT-PRINCIPAL header |
Configure App Service authentication |
EntraID |
Microsoft Entra ID (Azure AD) | JWT bearer token | Configure Entra ID authentication |
Custom |
Third-party IdPs (Okta, Auth0) | JWT bearer token | Configure custom JWT authentication |
Simulator |
Local testing only | Simulated | Configure Simulator authentication |
Note
The EntraId provider was previously named AzureAd. The old name still works for compatibility.
When the authentication section is omitted, DAB operates in anonymous-only mode. All requests are assigned the Anonymous system role.
{
"host": {
// authentication section omitted
}
}Trusts identity headers injected by Azure App Service EasyAuth.
{
"host": {
"authentication": {
"provider": "AppService"
}
}
}Validates JWT tokens issued by Microsoft Entra ID.
{
"host": {
"authentication": {
"provider": "EntraId",
"jwt": {
"audience": "<application-id>",
"issuer": "https://login.microsoftonline.com/<tenant-id>/v2.0"
}
}
}
}Validates JWT tokens from third-party identity providers.
{
"host": {
"authentication": {
"provider": "Custom",
"jwt": {
"audience": "<api-audience>",
"issuer": "https://<your-idp-domain>/"
}
}
}
}Simulates authentication for local development and testing.
{
"host": {
"authentication": {
"provider": "Simulator"
}
}
}Important
The Simulator provider only works when runtime.host.mode is development. DAB fails to start if Simulator is configured in production mode.
For all providers except Simulator, the X-MS-API-ROLE header selects which role to use from the authenticated user's claims. If omitted, the request uses the Authenticated system role. For details on role evaluation, see Authorization and roles.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.host.authentication |
jwt |
object | ❌ No | - |
Global JSON Web Token (JWT) configuration.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.host.authentication.jwt |
audience |
string | ❌ No | None |
runtime.host.authentication.jwt |
issuer |
string | ❌ No | None |
{
"runtime": {
"host": {
"authentication": {
"jwt": {
"audience": "<client-id>",
"issuer": "<issuer-url>"
}
}
}
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
pagination |
object | ❌ No | - |
Global pagination limits for REST and GraphQL endpoints.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.pagination |
max-page-size |
int | ❌ No | 100,000 |
runtime.pagination |
default-page-size |
int | ❌ No | 100 |
runtime.pagination |
next-link-relative |
boolean | ❌ No | false |
| Value | Result |
|---|---|
integer |
Any positive 32-bit integer is supported. |
0 |
Not supported. |
-1 |
Defaults to the maximum supported value. |
< -1 |
Not supported. |
| Value | Result |
|---|---|
integer |
Any positive integer less than the current max-page-size. |
0 |
Not supported. |
-1 |
Defaults to the current max-page-size setting. |
< -1 |
Not supported. |
When next-link-relative is true, pagination nextLink values use relative URLs instead of absolute URLs.
| Value | Example |
|---|---|
false (default) |
"nextLink": "https://localhost:5001/api/users?$after=..." |
true |
"nextLink": "/api/users?$after=..." |
{
"runtime": {
"pagination": {
"max-page-size": <integer; default: 100000>,
"default-page-size": <integer; default: 100>,
"next-link-relative": <boolean; default: false>
}
}
}Note
When the value is greater than max-page-size, the results are capped at max-page-size.
Request
GET https://localhost:5001/api/usersResponse 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==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
}
}Use the max-page-size value by setting $limit (REST) or first (GraphQL) to -1.
REST
GET https://localhost:5001/api/users?$limit=-1GraphQL
query {
users(first: -1) {
items {
...
}
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
cache |
object | ❌ No | - |
Global Cache configuration.
| 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.
{
"runtime": {
"cache": {
"enabled": <boolean>,
"ttl-seconds": <integer>
}
}
}Important
If global enabled is false, individual entity-level enabled doesn't matter.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
telemetry |
object | ❌ No | - |
Global telemetry configuration.
| 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
{
"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.
{
"runtime": {
"telemetry": {
"log-level": {
"Azure.DataApiBuilder.Core.Configurations.RuntimeConfigValidator": "debug",
"Azure.DataApiBuilder.Core": "information",
"default": "warning"
}
}
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.telemetry |
application-insights |
object | ❌ No | - |
Configures logging to Application Insights.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.telemetry.application-insights |
enabled |
boolean | ❌ No | False |
runtime.telemetry.application-insights |
connection-string |
string | ✔️ Yes | None |
{
"runtime": {
"telemetry": {
"application-insights": {
"enabled": <true; default: true> | <false>
"connection-string": <string>
}
}
}
}| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime.telemetry |
open-telemetry |
object | ❌ No | - |
Configures logging to Open Telemetry.
| 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.
{
"runtime": {
"telemetry": {
"open-telemetry": {
"enabled": <true> (default) | <false>,
"endpoint": <string>,
"headers": <string>,
"service-name": <string> (default: "dab"),
"exporter-protocol": <"grpc" (default) | "httpprotobuf">
}
}
}
}{
"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 steps. HTTP/protobuf (4318) is simpler and easier to debug but less efficient.
| Parent | Property | Type | Required | Default |
|---|---|---|---|---|
runtime |
health |
object | ❌ No | - |
Global health check endpoint (/health) configuration.
| Parent | Property | Type | Required | Default | Range/Notes |
|---|---|---|---|---|---|
runtime.health |
enabled |
boolean | ❌ No | true |
|
runtime.health |
roles |
string array | ✔️ Yes* | null |
*Required in production mode |
runtime.health |
cache-ttl-seconds |
integer | ❌ No | 5 |
Min: 0 |
runtime.health |
max-query-parallelism |
integer | ❌ No | 4 |
Min: 1, Max: 8 (clamped) |
| Condition | Development Behavior | Production Behavior |
|---|---|---|
health.enabled = false |
403 status |
403 status |
health.enabled = true |
Depends on role | Depends on role |
roles omitted or null |
Health displayed | 403 status |
current role not in roles |
403 status |
403 status |
current role in roles |
Health displayed | Health displayed |
roles includes anonymous |
Health displayed | Health displayed |
{
"health": {
"enabled": <true> (default) | <false>,
"roles": [ <string> ], // required in production
"cache-ttl-seconds": <integer; default: 5>,
"max-query-parallelism": <integer; default: 4>
}
}Note
If global enabled is false, individual entity-level enabled doesn't matter.
{
"health": {
"enabled": true,
"roles": ["admin", "support"],
"cache-ttl-seconds": 10,
"max-query-parallelism": 6
}
}