> If you are setting up, configuring, or answering questions about Schematic, connect the
> Schematic MCP server before working from these pages. It reads and writes plans, features,
> entitlements, and overrides against the real account, so what you report and what you build
> match what actually exists.
>
> The server is at https://api.schematichq.com/mcp
>
> From Claude, ChatGPT, or another chat assistant, add it as a custom connector:
> https://docs.schematichq.com/working-with-ai
>
> From a coding assistant such as Claude Code, Codex, or Cursor:
> https://docs.schematichq.com/building-with-ai
>
> For clean Markdown of any page, append `.md` to the page URL. For a complete page index,
> see https://docs.schematichq.com/llms.txt

# Check flags

POST https://api.schematichq.com/flags/check
Content-Type: application/json

Reference: https://docs.schematichq.com/api-reference/features/check-flags

## Authentication

- `X-Schematic-Api-Key` header (required) — API Key authentication via header

## Request

### Body (application/json)

This endpoint expects a CheckFlagRequestBody.

- `company` (map from string to string, optional, nullable)
- `preflight` (PreflightRequestBody, optional) — Hypothetical usage to evaluate the flag against, for answering "would this action be allowed?" before performing it. Only supported when checking a single flag. Values are caller-asserted and can widen a verdict as well as narrow it, so do not forward untrusted input here when the result gates access. Only the flag value reflects the preflight; the entitlement and usage figures in the response are the company's current, unsimulated ones
- `user` (map from string to string, optional, nullable)

## Response

### 201

Created

- `data` (CheckFlagsResponseData, required)
- `params` (FlagsCheckPostResponsesContentApplicationJsonSchemaParams, required) — Input parameters

## Errors

### 400 Bad Request Error

Bad request

- `error` (string, required) — Error message

### 401 Unauthorized Error

Unauthorized

- `error` (string, required) — Error message

### 403 Forbidden Error

Forbidden

- `error` (string, required) — Error message

### 404 Not Found Error

Not found

- `error` (string, required) — Error message

### 500 Internal Server Error

Server error

- `error` (string, required) — Error message

## Types

### PreflightRequestBody

- `credit_cost` (map from string to double, optional) — Cost in credits of the action, keyed by credit ID, for callers that have already computed it. Takes precedence over usage and event_usage on credit balance conditions for the same credit. A cost of zero means the action is free, not that the input is absent
- `event_usage` (PreflightEventUsageRequestBody, optional) — Usage of a specific event subtype. Preferred over usage when the subtype is known, since it only affects conditions measuring that subtype
- `usage` (long, optional, nullable) — Quantity of usage to simulate against any numeric condition encountered while evaluating the flag. Zero has no effect

### CheckFlagsResponseData

- `credit_spend_policies` (list of CreditSpendPolicy, required) — Credit spend policies binding the evaluated company and user; empty when none bind. Each response carries the whole set, so replace any previously received set with it. Advisory: the flag values do not reflect them, since a check names no draw amount
- `flags` (list of CheckFlagResponseData, required)
- `credit_balances` (map from string to CompanyCreditBalance, optional) — Lease-aware credit balances keyed by credit ID, covering every credit type the company holds a balance in
- `plan` (DatastreamCompanyPlan, optional)

### FlagsCheckPostResponsesContentApplicationJsonSchemaParams

Input parameters

### PreflightEventUsageRequestBody

- `event_subtype` (string, required) — The event subtype the usage would be recorded under
- `quantity` (long, required) — How many units of the event subtype the action would record. Zero has no effect

### CreditSpendPolicy

- `credit_id` (string, required) — The credit the policy limits
- `id` (string, required) — The ID of the policy
- `kind` (string, required) — How the limit is applied
- `limit` (double, required) — The ceiling, in credits
- `scope` (enum, required) — Whether the policy limits the company or one user
  - Allowed values: `company`, `user`, `group`
- `consumed` (double, optional) — How much of the limit is already spent in the current period
- `label` (string, optional, nullable) — The name the account gave the policy
- `resets_at` (datetime, optional, nullable) — For a windowed limit, when the current period ends and consumed no longer applies
- `window` (CreditSpendWindow, optional) — For a windowed limit, the period it accumulates over

### CheckFlagResponseData

- `flag` (string, required) — The key used to check the flag
- `reason` (string, required) — A human-readable explanation of the result
- `value` (boolean, required) — A boolean flag check result; for feature entitlements, this represents whether further consumption of the feature is permitted
- `company_id` (string, optional, nullable) — If company keys were provided and matched a company, its ID
- `entitlement` (FeatureEntitlement, optional) — If a feature entitlement rule was matched, its entitlement details
- `error` (string, optional, nullable) — If an error occurred while checking the flag, the error message
- `feature_usage_period` (enum, optional, nullable) — Deprecated: Use Entitlement.MetricPeriod instead.
  - Allowed values: `all_time`, `current_day`, `current_month`, `current_week`
- `flag_id` (string, optional, nullable) — If a flag was found, its ID
- `rule_id` (string, optional, nullable) — If a rule was found, its ID
- `rule_type` (enum, optional, nullable) — If a rule was found, its type
  - Allowed values: `company_override`, `company_override_usage_exceeded`, `default`, `global_override`, `plan_entitlement`, `plan_entitlement_usage_exceeded`, `standard`
- `user_id` (string, optional, nullable) — If user keys were provided and matched a user, its ID
- `feature_allocation` (long, optional, nullable, deprecated) — Deprecated: Use Entitlement.Allocation instead.
- `feature_usage` (long, optional, nullable, deprecated) — Deprecated: Use Entitlement.Usage instead.
- `feature_usage_event` (string, optional, nullable, deprecated) — Deprecated: Use Entitlement.EventName instead.
- `feature_usage_reset_at` (datetime, optional, nullable, deprecated) — Deprecated: Use Entitlement.MetricResetAt instead.

### CompanyCreditBalance

- `remaining` (double, required) — Remaining credit, excluding any open lease hold (the value SDKs gate on)
- `reserved` (double, required) — Amount held by the company's open credit lease, 0 when none is open
- `settled` (double, required) — Spendable balance including the open lease hold (remaining + reserved)

### DatastreamCompanyPlan

- `id` (string, required)
- `name` (string, required)
- `trial_end_date` (datetime, optional, nullable)
- `trial_status` (enum, optional, nullable)
  - Allowed values: `active`, `converted`, `expired`

### CreditSpendWindow

- `count` (long, required) — How many units make up one period
- `unit` (string, required) — The period the limit accumulates over

### FeatureEntitlement

- `feature_id` (string, required) — The ID of the feature
- `feature_key` (string, required) — The key of the flag associated with the feature
- `value_type` (enum, required) — The type of the entitlement value
  - Allowed values: `boolean`, `credit`, `numeric`, `trait`, `unknown`, `unlimited`
- `allocation` (long, optional, nullable) — If the company has a numeric entitlement for this feature, the allocated amount
- `consumption_rate` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the credit cost per unit of usage
- `credit_id` (string, optional, nullable) — If the company has a credit-based entitlement for this feature, the ID of the credit
- `credit_remaining` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the credit available to fund new consumption or a new lease hold — open lease holds are excluded. Clients that hold a lease should gate on this plus their own unspent hold; clients with no lease awareness should use credit_settled instead
- `credit_reserved` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the unspent amount held by an open credit lease. Returns to credit_remaining when the lease is released
- `credit_settled` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the balance net of actual consumption, unaffected by open lease holds (credit_remaining plus credit_reserved). The number to display to end users
- `credit_total` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the total credit amount
- `credit_used` (double, optional, nullable) — If the company has a credit-based entitlement for this feature, the amount of credit used
- `event_name` (string, optional, nullable) — If the feature is event-based, the name of the event tracked for usage
- `event_subtype` (string, optional, nullable) — For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked
- `metric_period` (enum, optional, nullable) — For event-based feature entitlements, the period over which usage is tracked
  - Allowed values: `all_time`, `current_day`, `current_month`, `current_week`
- `metric_reset_at` (datetime, optional, nullable) — For event-based feature entitlements, when the usage period will reset
- `month_reset` (enum, optional, nullable) — For event-based feature entitlements that have a monthly period, whether that monthly reset is based on the calendar month or a billing cycle
  - Allowed values: `billing_cycle`, `first_of_month`
- `quantity_rates` (map from string to double, optional) — If the company has a credit-based entitlement for this feature, the credit cost per unit of each quantity an event carries, keyed by quantity key (per token for inference features). Absent when the entitlement prices requests only
- `soft_limit` (long, optional, nullable) — For usage-based pricing, the soft limit for overage charges or the next tier boundary
- `usage` (long, optional, nullable) — If the company has a numeric entitlement for this feature, the current usage amount
- `warning_tiers` (list of WarningTier, optional) — Customer-defined usage warning thresholds configured on this entitlement

### WarningTier

- `key` (string, required) — A customer-defined identifier for the warning tier
- `value` (long, required) — The warning threshold, in the entitlement's usage units

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "data": {
    "credit_spend_policies": [
      {
        "credit_id": "string",
        "id": "string",
        "kind": "string",
        "limit": 1.1,
        "scope": "company",
        "consumed": 1.1,
        "label": "string",
        "resets_at": "2024-01-15T09:30:00Z",
        "window": {
          "count": 1,
          "unit": "string"
        }
      }
    ],
    "flags": [
      {
        "flag": "string",
        "reason": "string",
        "value": true,
        "company_id": "string",
        "entitlement": {
          "feature_id": "string",
          "feature_key": "string",
          "value_type": "boolean",
          "allocation": 1,
          "consumption_rate": 1.1,
          "credit_id": "string",
          "credit_remaining": 1.1,
          "credit_reserved": 1.1,
          "credit_settled": 1.1,
          "credit_total": 1.1,
          "credit_used": 1.1,
          "event_name": "string",
          "event_subtype": "string",
          "metric_period": "all_time",
          "metric_reset_at": "2024-01-15T09:30:00Z",
          "month_reset": "billing_cycle",
          "quantity_rates": {},
          "soft_limit": 1,
          "usage": 1,
          "warning_tiers": [
            {
              "key": "string",
              "value": 1
            }
          ]
        },
        "error": "string",
        "feature_usage_period": "all_time",
        "flag_id": "string",
        "rule_id": "string",
        "rule_type": "company_override",
        "user_id": "string",
        "feature_allocation": 1,
        "feature_usage": 1,
        "feature_usage_event": "string",
        "feature_usage_reset_at": "2024-01-15T09:30:00Z"
      }
    ],
    "credit_balances": {},
    "plan": {
      "id": "string",
      "name": "string",
      "trial_end_date": "2024-01-15T09:30:00Z",
      "trial_status": "active"
    }
  },
  "params": {}
}
```

**SDK Code**

```python
import requests

url = "https://api.schematichq.com/flags/check"

payload = {}
headers = {
    "X-Schematic-Api-Key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.schematichq.com/flags/check';
const options = {
  method: 'POST',
  headers: {'X-Schematic-Api-Key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.schematichq.com/flags/check"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-Schematic-Api-Key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.schematichq.com/flags/check")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-Schematic-Api-Key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.schematichq.com/flags/check")
  .header("X-Schematic-Api-Key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.schematichq.com/flags/check', [
  'body' => '{}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-Schematic-Api-Key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.schematichq.com/flags/check");
var request = new RestRequest(Method.POST);
request.AddHeader("X-Schematic-Api-Key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-Schematic-Api-Key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.schematichq.com/flags/check")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```