Introduction
Learn how to authenticate, version, and debug requests across the Microsoft Foundry REST API surface.
Use the Microsoft Foundry REST API to create and manage project-scoped resources from any HTTP client. Start here to understand authentication, base URLs, versioning, preview headers, wire formats, and the client SDKs that map to the same API surface.
Making requests
Authentication
Authenticate each request with either a bearer token or an API key.
| Method | Header | When to use |
|---|---|---|
| Bearer token | Authorization: Bearer YOUR_ACCESS_TOKEN | Microsoft Entra ID, managed identity, or delegated auth flows |
| API key | api-key: YOUR_API_KEY | Server-to-server calls where key management is already in place |
For Microsoft Entra ID, request a token for the https://ai.azure.com/.default scope.
Base URL
Build project-scoped requests from this base pattern:
YOUR_ENDPOINTis your Foundry resource endpoint.YOUR_PROJECT_NAMEis the Project name in that resource.
Append the resource path and the api-version query parameter on every call.
API versioning
API versioning
The Foundry API uses a single version identifier. Pass it as a query parameter on every request to non-OpenAI endpoints.
| Endpoint type | Query parameter | Notes |
|---|---|---|
Foundry-native (/agents, /datasets, /indexes, etc.) | api-version=v1 | Required on every request |
OpenAI-compatible (/openai/v1/*) | (none) | These endpoints do not use api-version |
Preview features
Preview capabilities within the v1 API surface are gated by the Foundry-Features request header (e.g., Foundry-Features: Agents.CodeAgents=V1Preview) rather than by a separate API version.
| Feature family | Header |
|---|---|
| Hosted agents | Foundry-Features: HostedAgents=V1Preview |
| Agent endpoints | Foundry-Features: AgentEndpoints=V1Preview |
| Workflow agents | Foundry-Features: WorkflowAgents=V1Preview |
| Evaluations assets and rules | Foundry-Features: Evaluations=V1Preview |
| Skills | Foundry-Features: Skills=V1Preview |
| Toolboxes | Foundry-Features: Toolboxes=V1Preview |
Request and response format
JSON is the default wire format.
| Scenario | Header |
|---|---|
| Request with a body | Content-Type: application/json |
| Buffered JSON response | Accept: application/json |
| Streaming response | Accept: text/event-stream |
Set Content-Type only when you send a body. Use Accept: text/event-stream only for endpoints that document server-sent events.
Client SDKs
Use REST directly, or start from a language SDK when you want typed models, authentication helpers, and a more idiomatic client surface.
| Language | Package | Install |
|---|---|---|
| Python | azure-ai-projects | pip install azure-ai-projects |
| JavaScript | @azure/ai-projects | npm install @azure/ai-projects |
| C# | Azure.AI.Projects | dotnet add package Azure.AI.Projects |
| Java | azure-ai-projects | Add com.azure:azure-ai-projects as a Maven dependency |
See the SDK overview for language-specific reference links.
Troubleshooting
Debugging requests
Log enough metadata to trace failures across services and retries.
x-request-id: service-generated request identifierx-ms-client-request-id: client-supplied correlation identifierServer-Timing: optional processing details on some operations
For failed requests, log the full URL, status code, x-request-id, and x-ms-client-request-id. Reuse a client-generated request ID across retries so you can correlate a full attempt chain.
Error handling
Expect structured JSON errors from the API. Handle them consistently, log correlation IDs, and treat status codes as part of the contract.
Error envelope
Most errors use this shape:
Use error.code for branching logic when an operation documents stable codes. Use message for diagnostics, not for machine parsing.
Status codes
| Status code | Typical cause | Recommended action |
|---|---|---|
400 Bad Request | Missing field, malformed JSON, invalid syntax | Fix the request shape and try again |
401 Unauthorized | Missing token, expired token, invalid API key | Refresh credentials and resend |
403 Forbidden | Caller lacks permission on the Project or resource | Check RBAC, scope, and tenant context |
404 Not Found | Wrong route, missing resource ID, unsupported path | Verify the URL, identifiers, and API version |
409 Conflict | Operation collides with current resource state | Wait, refresh state, or resolve the conflict |
422 Unprocessable Entity | Request is well-formed but semantically invalid | Correct field values or unsupported combinations |
429 Too Many Requests | Resource or subscription limit exceeded | Honor Retry-After and retry with backoff |
500 Internal Server Error | Unexpected service-side failure | Retry with backoff and capture request IDs |
503 Service Unavailable | Temporary service unavailability or warm-up | Retry later and avoid hot-loop retries |
Correlation IDs
Every failed request should capture x-request-id. This is the fastest way to escalate an issue to support or an internal service owner. If you generate x-ms-client-request-id on the client, log that value too so you can connect retries and downstream logs.
Common error patterns
Authentication failures usually show up as 401 or 403. Check whether you sent the correct header, requested the right Entra scope, and targeted the intended Project.
Validation failures usually show up as 400 or 422. Inspect error.target and any entries in error.details before retrying.
Transient failures usually show up as 429, 500, or 503. These are the cases where retries help.
Rate limits
Microsoft Foundry can enforce limits at more than one layer. A request can hit a per-resource budget, such as requests per minute or concurrency, or a broader per-subscription or per-region quota for constrained preview capacity.
What to expect
When you exceed a limit, the service returns 429 Too Many Requests. If Retry-After is present, wait exactly that long before sending the next attempt.
If the response includes rate-limit metadata, log it with the failure. Common headers can include values such as a total limit, remaining budget, or reset time.
Retry strategy
Use exponential backoff with jitter when Retry-After is absent.
- Start with a short base delay.
- Exponentially increase the delay after each
429. - Add jitter so many clients do not retry at the same instant.
- Stop after a bounded number of attempts.
A good retry loop also keeps requests idempotent where possible. If an operation is not safe to replay, persist state before you retry or switch to an application-level recovery path.
Streaming and pagination
Some Microsoft Foundry operations stream incremental output. List operations can also split results across pages. Handle both contracts explicitly in your client.
Streaming with server-sent events
To receive incremental output, send Accept: text/event-stream and keep the connection open until you receive a terminal event or the [DONE] sentinel.
Each SSE event arrives as a block separated by a blank line.
Parse the stream incrementally instead of waiting for the full response body. Treat [DONE] as the terminal marker, then close the connection cleanly.
Reconnection strategy
SSE connections can drop because of network timeouts, client restarts, or proxies. If the operation is retry-safe, reconnect with exponential backoff and resume from application state when the endpoint supports it. If the operation is not safe to replay, surface a partial result and let the caller decide whether to restart.
Pagination
List operations can paginate in a few ways:
- Offset-style parameters such as
topandskip - Continuation tokens
- A
nextLinkURL in the response body
When nextLink is present, keep requesting pages until it is absent.
Preserve query parameters exactly when following a continuation URL. Do not reconstruct nextLink unless the API explicitly tells you to. That keeps your client compatible with token-based paging and future server-side changes.
Backwards compatibility
Expect additive changes between versions, and code defensively.
Breaking changes
- Removing fields, routes, or operations
- Changing response or request types
- Making optional fields required
- Adding new required headers
- Tightening validation rules
Non-breaking changes
- Adding optional fields
- Adding new endpoints
- Adding new enum values
- Clarifying documentation without changing behavior