# Product availability > Tell what is switched on where you call it, using checks the API already has. Section: Synapse and Locus. Web page: https://docs.katara.com/products/availability/ The Synapse and Locus guides and the [product API reference](https://docs.katara.com/product-api.txt) say what an operation does. Whether it is switched on where you call it is a separate question, and the one to ask first when an integration fails. A deployment enables each service by configuration. Most services are on or off for the whole deployment, not per account. Two things vary inside a deployment: an environment's product access, for each product and usage class, and the schedule runtime, which is enrolled separately for Test and Live. This page lists checks, not the state of any deployment. Run them against the environment you use. Start with the preflight, which answers most of them in one read; the rest of the page lists the narrower checks behind it and what each one proves. ## Ask the environment first `GET /katara/v1/orgs/{org_id}/environments/{environment_id}/preflight` reports what stands between an environment and each workflow, for the caller who asks. In the clients it is `getEnvironmentPreflight` and `get_environment_preflight`. It writes nothing, takes no lock on your records and spends nothing, so you can call it before every attempt. It needs `org:read`, which every role has; a key answers for its own environment only. Add `?workflow=` to ask about one of `managed_runs`, `ingestion`, `credential_execution`, `schedules`, `events`, `evaluation` or `image_description`. An unknown workflow is refused with `400` `invalid_request` and `param` set to `workflow`; so is any other query parameter, without a `param`. The reply describes the environment (`mode`, `state`, `reset_generation`), the caller (`kind` is `session`, `api_key` or `service_account`, with its role, its permissions here and whether its sign-in is `fresh`, which a key never is) and the setup you have under way, or `null`. Then, for each workflow: | Field | What it says | | --- | --- | | `available` and `message` | Whether this deployment runs the service. When it does not, `message` is the text its operations would answer `501` `feature_unavailable` with. For `image_description` it also needs a model in the catalog that accepts images | | `product_access` | Whether the environment has current access to each product the workflow uses, yes or no. No billing detail | | `credentials` | Who may start the workflow. Turning on a schedule or an event source takes a signed-in person, so those two list `session` only | | `permissions` | What the workflow needs, and which of those the caller lacks | | `items` | Whether each record the workflow needs exists: the agent, storage, an active policy, approved documents, a budget with funds left, the grants, a published version, content access, a payer's consent (Live only), a connected credential, and product access | | `workers` | Whether the background work it depends on is running: `ready`, `not_ready`, or `unknown` when nothing has ever reported | | `next_actions` | The steps left, in the action words error replies use, each with `requires_human` | | `ready` | True only when every line above is in place | The three kinds of answer stay apart. A switched-off service comes back as `available: false` with a `support` step. Missing authority is a `permissions.missing` entry with a `request_access` step, a `sign_in` step when only a person can start the workflow, or `reauthenticate` when you need to sign in again. A record nobody has made is an `items` entry with `present: false` and a step that names the item and the operation that makes it. `requires_human` is true when an API key or a service account cannot take the step: only a signed-in person can, as with funding a budget, consenting to pay, activating a policy or connecting a credential, or only someone whose role holds a permission the caller lacks. A worker that is not running gives a `retry` step. Worker readiness covers every running instance of the deployment, so it is the same whichever server answers. It never includes queue lengths or other load: those would describe other customers' work. Everything in the reply is true when it was read; the operation you call next checks again. ## Clients The [SDK examples](https://docs.katara.com/products/sdks.txt) and the tutorials use the TypeScript client (`@katara/platform`) and the Python client (`katara-platform`). Use the copy of each supplied for your environment, or call the API directly as [the curl guide](https://docs.katara.com/products/curl.txt) does. ## Is an operation served here Every answer under `/katara/v1/` uses Katara's JSON error envelope, so the code tells you what you have: | Answer | Meaning | | --- | --- | | `501` `feature_unavailable` | The service behind the operation is switched off in this deployment. The message names it | | `404` `route_not_found` | No operation matches the path | | `405` `method_not_allowed` | The path exists but not for that method. The `Allow` header lists the methods it takes | | `404` `not_found` | The operation is served and the resource is not there, or you cannot see it | An operation that is served refuses a request without credentials with `401` `unauthorized`. Both SDKs report each of these as `PlatformError` with its code and status. The preflight above reads the same switch for every workflow at once. ## Managed execution | Check | What it tells you | What it does not | | --- | --- | --- | | `createRun` answers `202` with an operation | The run was admitted and recorded as `queued` | That anything will execute it. Admission never asks whether workers are running | | `createRun` refused with `403` `product_access_unavailable` | The environment has no current Synapse access for that usage class | Anything about workers | | `createRun` refused with `429` `run_queue_full` or `409` `budget_unavailable` | The environment's queue is full, or the budget cannot cover the run | Anything about workers | | `getRun` moves past `queued` to `starting`, `running` or a terminal status | Execution picked the run up | That paid model calls, tools or sandboxes work | | A simulation run with the success fixture ends `completed` | The run path works end to end for simulation, at no cost | That paid Test Compute or Live work runs | The preflight's `runs` and `run_steps` workers say in advance whether runs are being started and carried out. A run that stays `queued` while both are `ready` is waiting for the environment's active limit. The free end-to-end check is still a simulation run, set up as in [Tutorial: run a managed agent](https://docs.katara.com/products/tutorial-managed-agent.txt). No check reports whether a code or browser sandbox can be placed before a run asks for one. ## Content storage | Check | What it tells you | What it does not | | --- | --- | --- | | `getStorageUsage` / `get_storage_usage`, field `offered` | Whether this deployment offers Katara storage. Needs a signed-in person | That your environment has a store | | `listContentStores` / `list_content_stores` | Which stores the environment has, with `kind` (`hosted` or `customer`) and `state`. Empty `data` means none | That uploads will succeed under your quota | | `createHostedStore` refused with `501` `capability_unsupported` | The deployment does not offer Katara storage; connect your own bucket | | Every content operation, and so every run, needs an active store in the environment. ## Scheduling | Check | What it tells you | What it does not | | --- | --- | --- | | `execution_ready` on `client.schedules.list`, `get` or `getVersion` (`get_version` in Python) | `true` once the deployment's schedule runtime has started for both Test and Live. Listing works with no schedules, so you can read it before publishing anything | That the runtime can reach its services now, that your environment's mode is enrolled, or that any occurrence will run | | A schedule's `runtime.state` | `unconfigured` means no runtime is enrolled for the environment's mode. The other states are described in [Schedule agent runs](https://docs.katara.com/products/schedules.txt#read-runtime-observations) | That an occurrence has run. `active` still needs current authority at each occurrence | | Enabling refused with `503` `schedule_execution_unavailable` | The schedule runtime is not running in this deployment | | Schedule reads need `synapse:schedules:write`, and reading `runtime` needs an owner, admin or operator role. `execution_ready` is the answer of the server that took your request; the preflight's `schedules` worker is `ready` while any server runs the schedule runtime, and needs only `org:read`. ## Event admission | Check | What it tells you | What it does not | | --- | --- | --- | | `execution_ready` on `client.eventSources.list`, `get` or `getVersion` (`client.event_sources` in Python) | `true` while the event admission worker is running and polling. It turns `false` while that worker is failing | That a source is enabled, that signatures verify, or that admitted events produce runs that execute | | Enabling refused with `503` `event_source_execution_unavailable` | Event admission is not running | | | A receipt still `pending` after its `expires_at` | The worker is not processing events: expiry is applied by the same worker | | | `POST .../events` answers `501` `feature_unavailable` | Event ingress is not served in this deployment | | Reads need `synapse:event_sources:write`; the preflight's `events` worker reports the same thing for every server under `org:read`. A receipt that is `admitted` carries a run ID; follow the run to see whether it executed. ## Evaluation | Check | What it tells you | What it does not | | --- | --- | --- | | `getEvaluationJudgeProfile` / `get_evaluation_judge_profile` returns a profile | Funded assessments are served in this deployment. `501` `feature_unavailable` means they are not | That the judge model is healthy or calibrated. The profile is a fixed description of how judging is done | | `client.evaluationCalibration.list` (`client.evaluation_calibration` in Python) answers | Calibration is served. It needs a signed-in person | That there are assessments to calibrate against | | `onlineEvaluation` / `online_evaluation`, field `approval.current` | Whether the approval a setting was turned on with still stands. A setting without one is never sampled | That the sampler is running in this deployment | | `evaluationSummary` / `evaluation_summary`, the `online` counts | How many completed runs live sampling considered, selected and had judged | Nothing in advance. Counts that stay at zero while Live runs complete mean nothing is sampling them | | `setOnlineEvaluation` turning sampling on refused with `503` `execution_unavailable` | Judge runs cannot be admitted in this deployment, because managed execution is off | | Turning sampling off always succeeds; see [Judging live traffic](https://docs.katara.com/products/evaluations.txt#judging-live-traffic). ## Paid compute | Check | What it tells you | What it does not | | --- | --- | --- | | `listEnvironments` / `list_environments`, field `live_funding` | Whether the deployment takes credits. Despite the name it covers Test Compute too: when it is `false`, neither Test Compute nor Live budgets can be funded | Your balance, your environment's product access, or whether runs execute | | `fundBudget` refused with `501` `capability_unsupported` | Credit funding is off in this deployment | | | `fundBudget` refused with `409` `budget_unavailable` | Your available credits cannot cover the budget | | | `fundBudget` or `createRun` refused with `409` `wallet_insufficient_funds` | The wallet's balance and allowance cannot cover the budget with your other wallet budgets and what it owes | Whether credits would cover it | | `createRun` refused with `409` `wallet_unpaid_limit` or `wallet_payment_failed` | The wallet owes its unpaid limit, or a collection from it failed and is unpaid | | Simulation budgets need no credits and work whatever `live_funding` says. ## Models and the simulation catalog | Check | What it tells you | What it does not | | --- | --- | --- | | `listAgentModels` / `list_agent_models` returns models | Those models are eligible for an agent definition now | That a run calling them will be paid for or answered | | `listAgentModels` answers `200` with empty `data` | No model is eligible, or the catalog could not be read from the marketplace | Which of the two | | `listAgentModels` refused with `503` `model_catalog_unavailable` | The agent model catalog is missing or stale in this deployment | | | `listSimulationFixtures` / `list_simulation_fixtures` | The fixed scenarios a Test simulation can run. It is never empty in Test and refused in Live | That a simulation run will execute | ## Image descriptions | Check | What it tells you | What it does not | | --- | --- | --- | | A managed run's description refused with `description_model_unavailable` | No model in this deployment's catalog accepts images, so nothing was stored or paid | When one will | | A managed run's description refused with `description_funding_unavailable` | The run's budget could not reserve the price of the call | Anything about the model | Descriptions are served where the document parser and paid model calls both are. The preflight's `image_description` workflow says in advance whether a run could have one: `available` is false with a `support` step when this deployment does not serve descriptions or no model in the catalog accepts images, and with a `retry` step when the catalog could not be read just then. It reads the catalog the description itself uses and calls no model. Its `permissions` are `synapse:runs:create`, `synapse:memory:read`, `cortex:inference` and `locus:actions:execute`; its `grants` item is present when the agent holds grants for both `cortex:inference` and `locus:actions:execute`, and its `document_reading` worker is the parser that renders the picture. `listAgentModels` lists the models an agent definition may name, which a description does not need. ## Product access Runs and sandbox access need the environment to hold current access to the product for the usage class. The preflight's `product_access` reads it without changing anything. A refused request says so too: `403` `product_access_unavailable`.