Full Code of microsoft/api-guidelines for AI

vNext 577874dc4909 cached
39 files
526.7 KB
123.4k tokens
1 requests
Download .txt
Showing preview only (546K chars total). Download the full file or copy to clipboard to get everything.
Repository: microsoft/api-guidelines
Branch: vNext
Commit: 577874dc4909
Files: 39
Total size: 526.7 KB

Directory structure:
gitextract_y88h3vd0/

├── .github/
│   └── CODEOWNERS
├── CONTRIBUTING.md
├── Guidelines.md
├── README.md
├── SECURITY.md
├── azure/
│   ├── .markdownlint.json
│   ├── ConsiderationsForServiceDesign.md
│   ├── Guidelines.md
│   ├── README.md
│   └── VersioningGuidelines.md
├── graph/
│   ├── Guidelines-deprecated.md
│   ├── GuidelinesGraph.md
│   ├── articles/
│   │   ├── collections.md
│   │   ├── coreTypes.md
│   │   ├── deprecation.md
│   │   ├── errorResponses.md
│   │   ├── filter-as-segment.md
│   │   ├── naming.md
│   │   └── nullable.md
│   └── patterns/
│       ├── PatternDescriptionTemplate.md
│       ├── alternate-key.md
│       ├── antiPatternTemplate.md
│       ├── change-tracking.md
│       ├── default-properties.md
│       ├── dictionary-client-guidance.md
│       ├── dictionary.md
│       ├── enums.md
│       ├── evolvable-enums.md
│       ├── facets.md
│       ├── flat-bag.md
│       ├── long-running-operations.md
│       ├── namespace.md
│       ├── navigation-property.md
│       ├── operations.md
│       ├── subsets.md
│       ├── subtypes.md
│       ├── upsert.md
│       └── viewpoint.md
└── license.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CODEOWNERS
================================================
# These are the set of folks who should review PRs on the azureRestUpdates branch.
#*  @microsoft/azure-api-stewardship-board @Azure/api-stewardship-board
/graph/ @microsoft/graphguidelinesapprovers


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to the Microsoft REST API Guidelines
The Microsoft REST API Guidelines is a Microsoft-wide initiative to develop consistent design guidelines for REST APIs. The initiative requires input and feedback from a variety of individuals both inside and outside of Microsoft.

To provide feedback, please follow the guidance in this document. Please note that these are just guidelines, not rules. Use your best judgment and feel free to propose changes to anything in this repository, including the contribution guidelines.

Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.
- [Creating issues](#creating-issues)
- [Recommended setup for contributing](#recommended-setup-for-contributing)
- [Documentation styleguide](#documentation-styleguide)
- [Commit messages](#commit-messages)
- [Pull requests](#pull-requests)

## Creating issues
- You can [create an issue][new-issue], but before doing that please read the bullets below and include as many details as possible.
- Perform a [cursory search][issue-search] to see if a similar issue has already been submitted.
- Reference the version of the Microsoft REST API Guidelines you are using.
- Include the guidance you expected and other places you've seen that guidance, e.g. [White House Web API Standards][white-house-api-guidelines].
- Include sample requests and responses whenever possible.

### Related repositories
This is the repository for Microsoft REST API Guidelines documentation only. Please ensure that you are opening issues in the right repository.

## Recommended setup for contributing
- Fork this repository on GitHub
- Install [Git][git] to your computer and clone your new forked repository
- Install [Atom][atom], [VS Code][vscode], or your favorite editor
- Install [markdown-toc package][markdown-toc]

## Documentation styleguide
- Use [GitHub-flavored markdown][gfm]
- Use syntax-highlighted examples liberally
- Trim trailing empty lines from HTTP requests
- Retain only essential headers for understanding the example
- Use valid (e.g., member names quoted), pretty-printed JSON with a 2 space indent
- Minimize JSON payloads by using ellipses
- Write one sentence per line.

### Example
#### Request

```http
GET http://services.odata.org/V4/TripPinServiceRW/People HTTP/1.1
Accept: application/json
```

#### Response

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "@nextLink":"http://services.odata.org/V4/TripPinServiceRW/People?$skiptoken=8",
  "value":[
    {
      "userName":"russellwhyte",
      "firstName":"Russell",
      "lastName":"Whyte",
      "emails":[
        "Russell@example.com",
        "Russell@contoso.com"
      ],
      "addressInfo":[
        {
          "address":"187 Suffolk Ln.",
          "city":{
            "countryRegion":"United States",
            "name":"Boise",
            "region":"ID"
          }
        }
      ],
      "gender":"Male",
    },
    ...
  ]
}
```

## Commit messages
- Use the present tense: "Change ...", not "Changed ..."
- Use the imperative mood: "Change ...", not "Changes ..."
- Limit the first line to 72 characters or less
- Reference issues and pull requests liberally

## Pull requests
Pull requests serve as the primary mechanism by which contributions are proposed and accepted. We recommend creating a [topic branch][topic-branch] and sending a pull request to the `vNext` branch from the topic branch. For additional guidance, read through the [GitHub Flow Guide][github-flow-guide].

Be prepared to address feedback on your pull request and iterate if necessary.

[code-of-conduct]: https://opensource.microsoft.com/codeofconduct/
[new-issue]: https://github.com/Microsoft/api-guidelines/issues/new
[issue-search]: https://github.com/Microsoft/api-guidelines/issues
[white-house-api-guidelines]: https://github.com/WhiteHouse/api-standards/blob/master/README.md
[topic-branch]: https://www.git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#Topic-Branches
[gfm]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown
[github-flow-guide]: https://guides.github.com/introduction/flow/
[atom-beautify]: https://atom.io/packages/atom-beautify
[atom]: https://atom.io/
[markdown-toc]: https://atom.io/packages/markdown-toc
[vscode]: https://code.visualstudio.com/
[git]: https://git-scm.com/


================================================
FILE: Guidelines.md
================================================
> # NOTICE TO READERS
> This document has been deprecated and has been moved to the [Microsoft REST API Guidelines deprecated](./graph/Guidelines-deprecated.md). Please refer to the notes below for the latest guidance.
> 
> ## **Guidance for Azure service teams**
> Azure service teams should use the companion documents, [Azure REST API Guidelines](./azure/Guidelines.md) and [Considerations for Service Design](./azure/ConsiderationsForServiceDesign.md), when building or modifying their services. These documents provide a refined set of guidance targeted specifically for Azure services. For more information, see the [README](./azure/README.md) in the Azure folder.
> 
> ## **Guidance for Microsoft Graph service teams**
> Graph service teams should reference the companion document, [Microsoft Graph REST API Guidelines](./graph/GuidelinesGraph.md) when building or modifying their services. This document and the associated pattern catalog provides a refined set of guidance targeted specifically for Microsoft Graph services.

---


================================================
FILE: README.md
================================================
# Microsoft REST API Guidelines
Thank you for your interest in the Microsoft REST API Guidelines. If you have landed here, you're probably interested in learning about APIs. If so, you are in the right place!
We publish these guidelines here with the aim of fostering dialogue and learning in the API community at large. We further hope that these guidelines might encourage other organizations to create guidelines that are appropriate for them and in turn, if they're able, to publish theirs.

### Guidance for Azure service teams
Azure service teams should reference the companion documents, [Azure REST API Guidelines](./azure/Guidelines.md) and [Considerations for Service Design](./azure/ConsiderationsForServiceDesign.md), when building or modifying their services. These documents provide a refined set of guidance targeted specifically for Azure services. For more information, please refer to the [README](./azure/README.md) in the Azure folder.

### Guidance for Microsoft Graph service teams
Graph service teams should reference the companion document, [Microsoft Graph REST API Guidelines](./graph/GuidelinesGraph.md) when building or modifying their services. This document and the associated pattern catalog provide a refined set of guidance targeted specifically for Microsoft Graph services.

[![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/)

## Code of Conduct
This project adopts the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

## This repository
This repository contains a collection of documents and related materials supporting the overall Microsoft REST API Guidelines initiative. To contribute to this repository, see the [contribution guidelines][contribution-guidance].

[contribution-guidance]: CONTRIBUTING.md


================================================
FILE: SECURITY.md
================================================
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->

## Security

Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).

If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.

## Reporting Security Issues

**Please do not report security vulnerabilities through public GitHub issues.**

Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).

If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).

You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 

Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:

  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
  * Full paths of source file(s) related to the manifestation of the issue
  * The location of the affected source code (tag/branch/commit or direct URL)
  * Any special configuration required to reproduce the issue
  * Step-by-step instructions to reproduce the issue
  * Proof-of-concept or exploit code (if possible)
  * Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly.

If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.

## Preferred Languages

We prefer all communications to be in English.

## Policy

Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).

<!-- END MICROSOFT SECURITY.MD BLOCK -->


================================================
FILE: azure/.markdownlint.json
================================================
{
  "default": true,
  "MD012": {
    "maximum": 2
  },
  "MD013": {
    "line_length": 500
  },
  "MD022": false,
  "MD031": false,
  "MD032": false,
  "MD033": {
    "allowed_elements": [ "sup" ]
  },
  "MD036": false
}

================================================
FILE: azure/ConsiderationsForServiceDesign.md
================================================
# Considerations for Service Design

<!-- cspell:ignore autorest, etag, idempotency, maxpagesize, openapi -->
<!-- markdownlint-disable MD033 -->

## History

| Date        | Notes                                                          |
| ----------- | -------------------------------------------------------------- |
| 2024-Mar-17 | Updated LRO guidelines                                         |
| 2024-Jan-17 | Added guidelines on returning string offsets & lengths         |
| 2022-Jul-15 | Update guidance on long-running operations                     |
| 2022-Feb-01 | Updated error guidance                                         |
| 2021-Sep-11 | Add long-running operations guidance                           |
| 2021-Aug-06 | Updated Azure REST Guidelines per Azure API Stewardship Board. |

## Introduction

Great APIs make your service usable to customers. They are intuitive, naturally reflecting and communicating the underlying model and its behavior. They lend themselves easily to client library implementations in multiple programming languages. And they don't "get in the way" of the developer, by remaining stable and predictable, _especially over time_.

This document provides Microsoft teams building Azure services with a set of guidelines that  help service teams build great APIs. The guidelines create APIs that are approachable, sustainable, and consistent across the Azure platform. We do this by applying a common set of patterns and web standards to the design and development of the API.
For developers, a well defined and constructed API enables them to build fault-tolerant applications that are easy to maintain, support, and grow. For Azure service teams, the API is often the source of code generation enabling a broad audience of developers across multiple languages.

Azure Service teams should engage the Azure HTTP/REST Stewardship Board early in the development lifecycle for guidance, discussion, and review of their API. In addition, it is good practice to perform a security review, especially if you are concerned about PII leakage, compliance with GDPR, or any other considerations relative to your situation.

It is critically important to design your service to avoid disrupting users as the API evolves:

<a href="#principles-api-versioning" name="principles-api-versioning">:white_check_mark:</a> **DO** implement API versioning starting with the very first release of the service.

<a href="#principles-compatibility" name="principles-compatibility">:white_check_mark:</a> **DO** ensure that customer workloads never break

<a href="#principles-backward-compatibility" name="principles-backward-compatibility">:white_check_mark:</a> **DO** ensure that customers are able to adopt a new version of service or SDK client library **without requiring code changes**

## Azure Management Plane vs Data Plane
_Note: Developing a new service requires the development of at least 1 (management plane) API and potentially one or more additional (data plane) APIs.  When reviewing v1 service APIs, we see common advice provided during the review._

A **management plane** API is implemented through the Azure Resource Manager (ARM) and is used to provision and control the operational state of resources.
A **data plane** API is used by developers to implement applications. Occasionally, some operations are useful for provisioning/control and applications. In this case, the operation can appear in both APIs.
Although, best practices and patterns described in this document apply to all HTTP/REST APIs, they are especially important for **data plane** services because it is the primary interface for developers using your service. The **management plane** APIs may have other preferred practices based on the conventions of the [Azure RPC](https://aka.ms/azurerpc).

## Start with the Developer Experience
A great API starts with a well thought out and designed service. Your service should define simple/understandable abstractions with each given a clear name that you use consistently throughout your API and documentation. There must also be an unambiguous relationship between these abstractions.

Follow these practices to create clear names for your abstractions:
- Don't invent fancy terms or use fancy words. Try explaining the abstraction to someone that is not a domain expert and then name the abstraction using similar verbiage.
- Don't include "throwaway" words in names, like "response", "object", "payload", etc.
- Avoid generic names. Names should be specific to the abstraction and highlight how it is different from other abstractions in your service or related services.
- Pick one word/term out of a set of synonyms and stick to it.

It is extremely difficult to create an elegant API that works well on top of a poorly designed service; the service team and customers will live with this pain for years to come. So, the service team should empathize with customers by:
- Building apps that consume the API
- Hold reviews and share what is learned with your team
- Get customer feedback from API previews
- Thinking about the code that a customer writes both before and after an HTTP operation
- Initializing and reading from the data structures your service requires
- Thinking about which errors are recoverable at runtime as opposed to indicating a bug in the customer code that must be fixed

The whole purpose of a preview to address feedback by improving abstractions, naming, relationships, API operations, and so on. It is OK to make breaking changes during a preview to improve the experience now so that it is sustainable long term.

## Focus on Hero Scenarios
It is important to realize that writing an API is, in many cases, the easiest part of providing a delightful developer experience. There are a large number of downstream activities for each API, e.g. testing, documentation, client libraries, examples, blog posts, videos, and supporting customers in perpetuity. In fact, implementing an API is of miniscule cost compared to all the other downstream activities.

_For this reason, it is **much better** to ship with fewer features and only add new features over time as required by customers._

Focusing on hero scenarios reduces development, support, and maintenance costs; enables teams to align and reach consensus faster; and accelerates the time to delivery. A telltale sign of a service that has not focused on hero scenarios is "API drift," where endpoints are inconsistent, incomplete, or juxtaposed to one another.

<a href="#hero-scenarios-design" name="hero-scenarios-design">:white_check_mark:</a> **DO** define "hero scenarios" first including abstractions, naming, relationships, and then define the API describing the operations required.

<a href="#hero-scenarios-examples" name="hero-scenarios-examples">:white_check_mark:</a> **DO** provide example code demonstrating the "Hero Scenarios".

<a href="#hero-scenarios-high-level-languages" name="hero-scenarios-high-level-languages">:white_check_mark:</a> **DO** consider how your abstractions will be represented in different high-level languages.

<a href="#hero-scenarios-hll-examples" name="hero-scenarios-hll-examples">:white_check_mark:</a> **DO** develop code examples in at least one dynamically typed language (for example, Python or JavaScript) and one statically typed language (for example, Java or C#) to illustrate your abstractions and high-level language representations.

<a href="#hero-scenarios-yagni" name="hero-scenarios-yagni">:no_entry:</a> **DO NOT** proactively add APIs for speculative features customers might want.

### Start with your API Definition
Understanding how your service is used and defining its model and interaction patterns--its API--should be one of the earliest activities a service team undertakes. It reflects the abstractions & naming decisions and makes it easy for developers to implement the hero scenarios.

<a href="#openapi-description" name="openapi-description">:white_check_mark:</a> **DO** create an [OpenAPI description](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) (with [autorest extensions](https://github.com/Azure/autorest/blob/master/docs/extensions/readme.md)) for the service API. The OpenAPI description is a key element of the Azure SDK plan and is essential for documentation, usability and discoverability of service APIs.

## Design for Change Resiliency
As you build out your service and API, there are a number of decisions that can be made up front that add resiliency to client implementations. Addressing these as early as possible will help you iterate faster and avoid breaking changes.

<a href="#resiliency-enums" name="resiliency-enums">:ballot_box_with_check:</a> **YOU SHOULD** use extensible enumerations. Extensible enumerations are modeled as strings - expanding an extensible enumeration is not a breaking change.

<a href="#resiliency-conditional-requests" name="resiliency-conditional-requests">:ballot_box_with_check:</a> **YOU SHOULD** implement [conditional requests](https://tools.ietf.org/html/rfc7232) early. This allows you to support concurrency, which tends to be a concern later on.

## Use Good Names

Good names for resources, properties, operations, and parameters are essential to a great developer experience.

Resources are described by nouns. Resource and property names must be descriptive and easy for customers to understand.
Use names that correspond to user scenarios rather than service implementation details, e.g. "Diagnosis" and not "TreeLeafNode".
Names should convey the value's purpose and not simply describe its structure, e.g. "ConfigurationSetting" and not "KeyValuePair".
Ease of understanding comes from familiarity and recognition; you should favor consistency with other Azure services, names in the product's portal/user interface, and industry standards.

Names should aid developers in discovering functionality without having to constantly refer to documentation.
Use common patterns and standard conventions to aid developers in correctly guessing common property names and meanings.
Use verbose naming patterns and avoid abbreviations other than
well-known acronyms in your service domain.

<a href="#naming-consistency" name="naming-consistency">:white_check_mark:</a> **DO** use the same name for the same concept and different names for different concepts wherever possible.

### Recommended Naming Conventions

The following are recommended naming conventions for Azure services:

<a href="#naming-collections" name="naming-collections">:white_check_mark:</a> **DO** name collections as plural nouns or plural noun phrases using correct English.

<a href="#naming-values" name="naming-values">:white_check_mark:</a> **DO** name values that are not collections as singular nouns or singular noun phrases.

<a href="#naming-adjective-before-noun" name="naming-adjective-before-noun">:ballot_box_with_check:</a> **YOU SHOULD** should place the adjective before the noun in names that contain both a noun and an adjective.

For example, `collectedItems` not `itemsCollected`

<a href="#naming-acronym-case" name="naming-acronym-case">:ballot_box_with_check:</a> **YOU SHOULD** case all acronyms as though they were regular words (i.e. lower camelCase).

For example, `nextUrl` not `nextURL`.

<a href="#naming-date-time" name="naming-date-time">:ballot_box_with_check:</a> **YOU SHOULD** use an "At" suffix in names of `date-time` values.

For example, `createdAt` not `created` or `createdDateTime`.

<a href="#naming-include-units" name="naming-include-units">:ballot_box_with_check:</a> **YOU SHOULD** use a suffix of the unit of measurement for values with a clear unit of measurement (such as bytes, miles, and so on). Use a generally accepted abbreviation for the units (e.g. "Km" rather than "Kilometers") when appropriate.

<a href="#naming-duration" name="naming-duration">:ballot_box_with_check:</a> **YOU SHOULD** use an int for time durations and include the time units in the name.

For example, `expirationDays` as `int` and not `expiration` as `date-time`.

<a href="#naming-brand-names" name="naming-brand-names">:warning:</a> **YOU SHOULD NOT** use brand names in resource or property names.

<a href="#naming-avoid-acronyms" name="naming-avoid-acronyms">:warning:</a> **YOU SHOULD NOT** use acronyms or abbreviations unless they are broadly understood for example, "ID" or "URL", but not "Num" for "number".

<a href="#naming-avoid-reserved-words" name="naming-avoid-reserved-words">:warning:</a> **YOU SHOULD NOT** use names that are reserved words in widely used programming languages (including C#, Java, JavaScript/TypeScript, Python, C++, and Go).

<a href="#naming-boolean" name="naming-boolean">:no_entry:</a> **DO NOT** use "is" prefix in names of `boolean` values, e.g. "enabled" not "isEnabled".

<a href="#naming-avoid-redundancy" name="naming-avoid-redundancy">:no_entry:</a> **DO NOT** use redundant words in names.

For example, `/phones/number` and not `phone/phoneNumber`.

### Common names

The following are recommended names for properties that match the associated description:

| Name | Description |
|------------- | --- |
| createdAt | The date and time the resource was created. |
| lastModifiedAt | The date and time the resource was last modified. |
| deletedAt | The date and time the resource was deleted. |
| kind   | The discriminator value for a polymorphic resource |
| etag | The entity tag used for optimistic concurrency control, when included as a property of a resource. |

### `name` vs `id`

<a href="#naming-name-vs-id" name="naming-name-vs-id">:white_check_mark:</a> **DO** use "Id" suffix for the name of the identifier of a resource.

This holds even in the case where the identifier is assigned by the user with a PUT/PATCH method.

## Use Previews to Iterate
Before releasing your API plan to invest significant design effort, get customer feedback, & iterate through multiple preview releases. This is especially important for V1 as it establishes the abstractions and patterns that developers will use to interact with your service.

<a href="#previews-hypotheses" name="previews-hypotheses">:ballot_box_with_check:</a> **YOU SHOULD**  write and test hypotheses about how your customers will use the API.

<a href="#previews-at-least-two" name="previews-at-least-two">:ballot_box_with_check:</a> **YOU SHOULD**  release and evaluate a minimum of 2 preview versions prior to the first GA release.

<a href="#previews-key-scenarios" name="previews-key-scenarios">:ballot_box_with_check:</a> **YOU SHOULD**  identify key scenarios or design decisions in your API that you want to test with customers, and ask customers for feedback and to share relevant code samples.

<a href="#previews-code-with" name="previews-code-with">:ballot_box_with_check:</a> **YOU SHOULD**  consider doing a _code with_ exercise in which you actively develop with the customer, observing and learning from their API usage.

<a href="#previews-share-results" name="previews-share-results">:ballot_box_with_check:</a> **YOU SHOULD**  capture what you have learned during the preview stage and share these findings with your team and with the API Stewardship Board.

## Communicate Deprecations
As your service evolves over time, it will be natural that you want to remove operations that are no longer needed. For example, additional requirements or new capability in your service, may have resulted in a new operation that, effectively, replaces an old one.
Azure has a well established breaking changes policy that describes how to approach these kinds of changes. As part of this policy, the service team is required to clearly communicate to customers when their API is changing, e.g. deprecating operations. Often, this is done via an email to the address that is attached to the Azure subscription.

However, given how many organizations are structured, it's common that this email address is different from the actual people writing code against your API. To address this, the service API should declare that it may return the `azure-deprecating` header, to indicate that this operation will be removed in the future. There is a simple string convention, specified in the [Azure REST API Guidelines](https://aka.ms/azapi/guidelines#deprecating-behavior-notification) that provides more information about the forthcoming deprecation.
This header is targeted at developers or operation professionals, and it is intended to give them enough information and lead time to properly adapt to this change. Your documentation should reference this header and encourage logging and alerting practices based on its presence.

## Avoid Surprises
A major inhibitor to adoption and usage is when an API behaves in an unexpected way. Often, these are subtle design decisions that seem benign at the time, but end up introducing significant downstream friction for developers.

One common area of friction for developers is _polymorphism_ -- where a value may have any of several types or structures.
Polymorphism can be beneficial in certain cases, e.g. as a way to express inheritance, but also creates friction because it requires the value to be introspected before being processed and cannot be represented in a natural/useful way in many nominally typed languages. The use of a discriminator field (`kind`) simplifies the introspection, but developers frequently end up having to explicitly cast the response to the appropriate type in order to use it.

Collections are another common area of friction for developers. It is important to define collections in a consistent manner within your service and across services of the platform.  In particular, features such as pagination, filtering, and sorting, when supported, should follow common API patterns. See [Collections](./Guidelines.md#collections) for specific guidance.

An important consideration when defining a new service is support for pagination.

<a href="#support-paging" name="support-paging">:ballot_box_with_check:</a> **YOU SHOULD** support server-side paging, even if your resource does not currently need paging. This avoids a breaking change when your service expands. See [Collections](./Guidelines.md#collections) for specific guidance.

Another consideration for collections is support for sorting the set of returned items with the _orderby_ query parameter.
Sorting collection results can be extremely expensive for a service to implement as it must retrieve all items to sort them. And if the operation supports paging (which is likely), then a client request to get another page may have to retrieve all items and sort them again to determine which items are on the desired page.

<a href="#paging-orderby" name="paging-orderby">:heavy_check_mark:</a> **YOU MAY** support `orderby` if customer scenarios really demand it and the service is confident that it can support it in perpetuity (even if the backing storage service changes someday).

Another important design pattern for avoiding surprises is idempotency. An operation is idempotent if it can be performed multiple times and have the same result as a single execution.
HTTP requires certain operations like GET, PUT, and DELETE to be idempotent, but for cloud services it is important to make _all_ operations idempotent so that clients can use retry in failure scenarios without risk of unintended consequences.
See the [HTTP Request / Response Pattern section of the Guidelines](./Guidelines.md#http-request--response-pattern) for detailed guidance on making operations idempotent.

## Action Operations

Most operations conform to one of the standard REST Create, Read, Update, Delete, or List (CRUDL) style of operations. We refer to all other operations as "action" operations. Some examples of action operations are to reboot a VM, or send an email.

It is good practice to define the path for action operations that is easily distinguished from any resource path of the service. When services allow user-specified resource ids (also a good practice), the recommended approach for this is:
1) constrain user-specified resource ids to allow only certain characters, such as alphanumeric and '-' or '_', and
2) use a special character not in the set of valid characters for resource names to distinguish the "action" in the path.

In Azure we recommend distinguishing action operations by appending a ':' followed by an action verb to the final path segment.  E.g.
```text
https://.../<resource-collection>/<resource-id>:<action>?<input parameters>
```

Other patterns are possible. The key consideration is to ensure that the path for an action operation
cannot collide with a resource path that contains user-specified resource ids.

## Long-Running Operations

Long-running operations (LROs) are an API design pattern that should be used when the processing of
an operation may take a significant amount of time -- longer than a client will want to block
waiting for the result.

The request that initiates a long-running operation returns a response that points to or embeds
a _status monitor_, which is an ephemeral resource that will track the status and final result of the operation.
The status monitor resource is distinct from the target resource (if any) and specific to the individual
operation request.

There are four types of LROs allowed in Azure REST APIs:

1. An LRO to create or replace a resource that involves additional long-running processing.
2. An LRO to delete a resource.
3. An LRO to perform an action on or with an existing resource (or resource collection).
4. An LRO to perform an action not related to an existing resource (or resource collection).

The following sections describe these patterns in detail.

### Create or replace a resource requiring additional long-running processing
<a href="#put-with-additional-long-running-processing"></a> <!-- Preserve anchor of previous heading -->

A special case of long-running operations that occurs often is a PUT operation to create or replace a resource
that involves some additional long-running processing.
One example is a resource that requires physical resources (e.g. servers) to be "provisioned" to make the resource functional.

In this case:
- The operation must use the PUT method (NOTE: PATCH is never allowed here)
- The URL identifies the resource being created or replaced.
- The request and response body have identical schemas & represent the resource.
- The request may contain an `Operation-Id` header that the service will use as
the ID of the status monitor created for the operation.
- If the `Operation-Id` matches an existing operation and the request content is the same,
treat as a retry and return the same response as the earlier request.
Otherwise fail the request with a `409-Conflict`.

```text
PUT /items/FooBar&api-version=2022-05-01
Operation-Id: 22

{
   "prop1": 555,
   "prop2": "something"
}
```

In this case the response to the initial request is a `201 Created` to indicate that
the resource has been created or `200 OK` when the resource was replaced.
The response body should be a representation of the resource that was created,
and should include a `status` field indicating the current status of the resource.
A status monitor is created to track the additional processing and the ID of the status monitor
is returned in the `Operation-Id` header of the response.
The response must also include an `Operation-Location` header for backward compatibility.
If the resource supports ETags, the response may contain an `etag` header and possibly an `etag` property in the resource.

```text
HTTP/1.1 201 Created
Operation-Id: 22
Operation-Location: https://items/operations/22
etag: "123abc"

{
  "id": "FooBar",
  "status": "Provisioning",
  "prop1": 555,
  "prop2": "something",
  "etag": "123abc"
}
```

The client will issue a GET to the status monitor to obtain the status of the operation performing the additional processing.

```text
GET https://items/operations/22?api-version=2022-05-01
```

When the additional processing completes, the status monitor indicates if it succeeded or failed.

```text
HTTP/1.1 200 OK

{
   "id": "22",
   "status": "Succeeded"
}
```

If the additional processing failed, the service may delete the original resource if it is not usable in this state,
but should clearly document this behavior.

### Long-running delete operation

A long-running delete operation returns a `202 Accepted` with a status monitor which the client uses to determine the outcome of the delete.

The resource being deleted should remain visible (returned from a GET) until the delete operation completes successfully.

When the delete operation completes successfully, a client must be able to create a new resource with the same name without conflicts.

This diagram illustrates how a long-running DELETE operation is initiated and then how the client
determines it has completed and obtains its results:

```mermaid
sequenceDiagram
    participant Client
    participant API Endpoint
    participant Status Monitor
    Client->>API Endpoint: DELETE
    API Endpoint->>Client: HTTP/1.1 202 Accepted<br/>{ "id": "22", "status": "NotStarted" }
    Client->>Status Monitor: GET
    Status Monitor->>Client: HTTP/1.1 200 OK<br/>Retry-After: 5<br/>{ "id": "22", "status": "Running" }
    Client->>Status Monitor: GET
    Status Monitor->>Client: HTTP/1.1 200 OK<br/>{ "id": "22", "status": "Succeeded" }
```

1. The client sends the request to initiate the long-running DELETE operation.
The request may contain an `Operation-Id` header that the service uses as the ID of the status monitor created for the operation.

2. The service validates the request and initiates the operation processing.
If there are any problems with the request, the service responds with a `4xx` status code and error response body.
Otherwise the service responds with a `202-Accepted` HTTP status code.
The response body is the status monitor for the operation including the ID, either from the request header or generated by the service.
When returning a status monitor whose status is not in a terminal state, the response must also include a `retry-after` header indicating the minimum number of seconds the client should wait
before polling (GETing) the status monitor URL again for an update.
For backward compatibility, the response must also include an `Operation-Location` header containing the absolute URL
of the status monitor resource, including an api-version query parameter.

3. After waiting at least the amount of time specified by the previous response's `Retry-after` header,
the client issues a GET request to the status monitor using the ID in the body of the initial response.
The GET operation for the status monitor is documented in the REST API definition and the ID
is the last URL path segment.

4. The status monitor responds with information about the operation including its current status,
which should be represented as one of a fixed set of string values in a field named `status`.
If the operation is still being processed, the status field will contain a "non-terminal" value, like `NotStarted` or `Running`.

5. After the operation processing completes, a GET request to the status monitor returns the status monitor with a status field set to a terminal value -- `Succeeded`, `Failed`, or `Canceled` -- that indicates the result of the operation.
If the status is `Failed`, the status monitor resource contains an `error` field with a `code` and `message` that describes the failure.

6. There may be some cases where a long-running DELETE operation can be completed before the response to the initial request.
In these cases, the operation should still return a `202 Accepted` with the `status` property set to the appropriate terminal state.

7. The service is responsible for purging the status monitor resource.
It should auto-purge the status monitor resource after completion (at least 24 hours).
The service may offer DELETE of the status monitor resource due to GDPR/privacy.

### Long-running Action Operations

An action operation that is also long-running combines the [Action Operations](#action-operations) pattern
with the [Long Running Operations](#long-running-operations) pattern.

The operation is initiated with a POST operation and the operation path ends in `:<action>`.
A long-running POST should not be used for resource create: use PUT as described above.
PATCH must never be used for long-running operations: it should be reserved for simple resource updates.
If a long-running update is required it should be implemented with POST.

```text
POST /<service-or-resource-url>:<action>?api-version=2022-05-01
Operation-Id: 22

{
   "arg1": 123
   "arg2": "abc"
}
```

A long-running action operation returns a `202 Accepted` response with the status monitor in the response body.

```text
HTTP/1.1 202 Accepted
Operation-Location: https://<status-monitor-endpoint>/22

{
   "id": "22",
   "status": "NotStarted"
}
```

The client will issue a GET to the status monitor to obtain the status and result of the operation.

```text
GET https://<status-monitor-endpoint>/22?api-version=2022-05-01
```

When the operation completes successfully, the result (if there is one) will be included in the `result` field of the status monitor.

```text
HTTP/1.1 200 OK

{
   "id": "22",
   "status": "Succeeded",
   "result": { ... }
}
```

This diagram illustrates how a long-running action operation is initiated and then how the client
determines it has completed and obtains its results:

```mermaid
sequenceDiagram
    participant Client
    participant API Endpoint
    participant Status Monitor
    Client->>API Endpoint: POST
    API Endpoint->>Client: HTTP/1.1 202 Accepted<br/>{ "id": "22", "status": "NotStarted" }
    Client->>Status Monitor: GET
    Status Monitor->>Client: HTTP/1.1 200 OK<br/>Retry-After: 5<br/>{ "id": "22", "status": "Running" }
    Client->>Status Monitor: GET
    Status Monitor->>Client: HTTP/1.1 200 OK<br/>{ "id": "22", "status": "Succeeded", "result": { ... } }
```

1. The client sends the request to initiate the long-running action operation.
The request may contain an `Operation-Id` header that the service uses as the ID of the status monitor created for the operation.

2. The service validates the request and initiates the operation processing.
If there are any problems with the request, the service responds with a `4xx` status code and error response body.
Otherwise the service responds with a `202-Accepted` HTTP status code.
The response body is the status monitor for the operation including the ID, either from the request header or generated by the service.
When returning a status monitor whose status is not in a terminal state, the response must also include a `retry-after` header indicating the minimum number of seconds the client should wait
before polling (GETing) the status monitor URL again for an update.
For backward compatibility, the response may also include an `Operation-Location` header containing the absolute URL
of the status monitor resource, including an api-version query parameter.

3. After waiting at least the amount of time specified by the previous response's `Retry-after` header,
the client issues a GET request to the status monitor using the ID in the body of the initial response.
The GET operation for the status monitor is documented in the REST API definition and the ID
is the last URL path segment.

4. The status monitor responds with information about the operation including its current status,
which should be represented as one of a fixed set of string values in a field named `status`.
If the operation is still being processed, the status field will contain a "non-terminal" value, like `NotStarted` or `Running`.

5. After the operation processing completes, a GET request to the status monitor returns the status monitor with a status field set to a terminal value -- `Succeeded`, `Failed`, or `Canceled` -- that indicates the result of the operation.
If the status is `Failed`, the status monitor resource contains an `error` field with a `code` and `message` that describes the failure.
If the status is `Succeeded`, the operation results (if any) are returned in the `result` field of the status monitor.

6. There may be some cases where a long-running action operation can be completed before the response to the initial request.
In these cases, the operation should still return a `202 Accepted` with the `status` property set to the appropriate terminal state.

7. The service is responsible for purging the status monitor resource.
It should auto-purge the status monitor resource after completion (at least 24 hours).
The service may offer DELETE of the status monitor resource due to GDPR/privacy.

### Long-running action operation not related to a resource

When a long-running action operation is not related to a specific resource (a batch operation is one example),
another approach is needed.

This type of LRO should be initiated with a PUT method on a URL that represents the operation to be performed,
and includes a final path parameter for the user-specified operation ID.
The response of the PUT includes a response body containing a representation of the status monitor for the operation
and an `Operation-Location` response header that contains the absolute URL of the status monitor.
In this type of LRO, the status monitor should include any information from the request used to initiate the operation,
so that a failed operation could be reissued if necessary.

Clients will use a GET on the status monitor URL to obtain the status and results of the operation.
Since the HTTP semantic for PUT is to create a resource, the same schema should be used for the PUT request body,
the PUT response body, and the response body of the GET for the status monitor for the operation.
For this type of LRO, the status monitor URL should be the same URL as the PUT operation.

The following examples illustrate this pattern.

```text
PUT /translate-operations/<operation-id>?api-version=2022-05-01

<JSON body with parameters for the operation>
```

Note that the client specifies the operation id in the URL path.

A successful response to the PUT operation should have a `201 Created` status and response body
that contains a representation of the status monitor _and_ any information from the request used to initiate the operation.

The service is responsible for purging the status monitor after some period of time,
but no earlier than 24 hours after the completion of the operation.
The service may offer DELETE of the status monitor resource due to GDPR/privacy.

### Controlling a long-running operation

It might be necessary to support some control action on a long-running operation, such as cancel.
This is implemented as a POST on the status monitor endpoint with `:<action>` added.

```text
POST /<status-monitor-endpoint>:cancel?api-version=2022-05-01
```

A successful response to a control operation should be a `200 OK` with a representation of the status monitor.

```text
HTTP/1.1 200 OK

{
   "id": "22",
   "status": "Canceled"
}
```

## Errors
One of the most important parts of service design is also one of the most overlooked.  The errors returned by your service are a critical part of your developer experience and are part of your API contract.  Your service and your customer's application together form a distributed system.  Errors are inevitable, but well-designed errors can help you avoid costly customer support incidents by empowering customers to self-diagnose problems.

First, you should always try to design errors out of existence if possible.  You'll get a lot of this for free by following the [API Guidelines](https://aka.ms/azapi/guidelines).  Some examples include:
- Idempotent APIs solve a whole class of network issues where customers have no idea how to proceed if they send a request to the service but never get a response.
- Accessing resources from multiple microservices can quickly lead to complex race conditions. These can be avoided by supporting conditional requests through an [optimistic concurrency strategy](https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#optimistic-concurrency), e.g. by leveraging `If-Match`/`If-None-Match` request headers.
- Reframing the purpose of an API can obviate some errors.  This is most often specific to your operations, but an [example from the API Guidelines](https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#http-return-codes) is thinking about `DELETE`s as _"ensure no resource at this location exists"_ so they can return an easier to use `204` instead of _"delete this exact resource instance"_ which would fail with a `404`.

There are two types of errors returned from your service and customers handle them differently.
- Usage errors where the customer is calling your API incorrectly.  The customer can easily make these errors go away by fixing their code.  We expect most usage errors to be found during testing.
- Runtime errors that can't be prevented by the customer and need to be recovered from.  Some runtime errors like `429` throttling will be handled automatically by client libraries, but most will be situations like a `409` conflict requiring knowledge about the customer's application to remedy.

You should use appropriate [HTTP status codes](https://developer.mozilla.org/docs/Web/HTTP/Status#client_error_responses) for customers to handle errors generically and error code strings in our common error schema and the `x-ms-error-code` header for customers to handle errors specifically.  As an example, consider what a customer would do when trying to get the properties of a Storage blob:
- A `404` status code tells them the blob doesn't exist and the customer can report the error to their users
- A `BlobNotFound` or `ContainerNotFound` error code will tell them why the blob doesn't exist so they can take steps to recreate it

The [common error schema in the Guidelines](https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#handling-errors) allows nested details and inner errors that have their own error codes, but the top-level error code is the most important.  The HTTP status code and the top-level error code are the only part of your error that we consider part of your API contract that follows the same compatibility requirements as the rest of your API.
Importantly, this means you **changing the HTTP status code or top-level error code for an API is a breaking change**.
You can only return new status codes and error codes in future API versions if customers make use of new features that trigger new classes of errors.  Battle tested error handling is some of the hardest code to get right and we can't break that for customers when they upgrade to the latest version.  The rest of the properties in your error like `message`, `details`, etc., are not considered part of your API contract and can change to improve the diagnosability of your service.

You should also return the top-level error code as the `x-ms-error-code` response header so client libraries have the ability to automatically retry requests when possible without having to parse a JSON payload.  We recommend unique error codes like `ContainerBeingDeleted` for every distinct recoverable error that can occur, but suggest reusing common error codes like `InvalidHeaderValue` for usage errors where a descriptive error message is more important for resolving the problem.
The Storage [Common](https://docs.microsoft.com/rest/api/storageservices/common-rest-api-error-codes) and [Blob](https://docs.microsoft.com/rest/api/storageservices/blob-service-error-codes) error codes are a good starting point if you're looking for examples.
You can [define an enum in your spec](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/storage/data-plane/Microsoft.BlobStorage/preview/2021-04-10/blob.json#L10419) with `"modelAsString": true` that lists all of the top-level error codes to make it [easier for your customers to handle specific error codes](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/storage/Azure.Storage.Blobs#troubleshooting).

You should not document specific error status codes in your OpenAPI/Swagger spec.  The `"default"` response is the only thing AutoRest considers an error response unless you provide other annotations.  Every unique status code turns into a separate code path in your client libraries so we do not encourage this practice.  The only reason to document specific error status codes is if they return a different error response than the default, but that is also heavily discouraged.

Be as precise as possible when writing error messages.  A message with just `Invalid Argument` is almost useless to a customer who sent 100KB of JSON to your endpoint.  ``Query parameter `top` must be less than or equal to 1000`` tells a customer exactly what went wrong so they can quickly fix the problem.
Don't go overboard while writing great, understandable error messages and include any sensitive customer information or secrets though.  Many developers will blindly write any error to logs that don't have the same level of access control as Azure resources.

All responses should include the `x-ms-request-id` header with a unique id for the request, but this is particularly important for error responses.  Service logs for the request should contain the `x-ms-request-id` so that support staff can use this value to diagnose specific customer reported errors.

Finally, write sample code for your service's workflow and add the code you'd want customers using to gracefully recover from errors.  Is it actually graceful?  Is it something you'd be comfortable asking most customers to write?
We also highly encourage reaching out to customers during private preview and asking them for code they've written against your service.  Their error handling might match your expectations, you might find a strong need for better documentation, or you might find important opportunities to improve the errors you're returning.

## Pagination

Operations that return a collection of resources must consider pagination.
There are hard limits to the payload size of HTTP responses, and when the size of a collection or the resources themselves
can grow arbitrarily large there is the risk of exceeding this limit if the operation does not support pagination.
Further, adding support for pagination is a breaking change so it should be supported in the initial GA of the service
if there is any possibility that it will eventually be needed.

There are two forms of pagination that MAY be supported by RESTful APIs.
Server-driven paging mitigates against denial-of-service attacks by forcibly paginating a request over multiple response payloads.
Client-driven paging enables clients to request only the number of resources that it can use at a given time.
Services should almost always support server-driven paging and may optionally support client-driven paging.

### Server-driven paging

In server-driven paging, the service includes a `nextLink` property in the response to indicate that additional elements
exist in the collection.
The value of the `nextLink` property should be an opaque absolute URL that will return the next page of results.
The absence of a `nextLink` property means that no additional pages are available.
Since `nextLink` is an opaque URL it should include any query parameters required by the service, including `api-version`.
The service should honor a request to a URL derived from `nextLink` by replacing the value for the `apl-version` query parameter
with a different but valid api version. The service may reject the request if any other element of `nextLink` was modified.

The service determines how many items to include in the response and may choose a different number for different collections and even for different pages of the same collection.
An operation may allow the client to specify a maximum number of items in a response with an optional `maxpagesize` parameter.
Operations that support `maxpagesize` should return no more than the value specified in `maxpagesize` but may return fewer.

### Client-driven paging

An operation may support `skip` and `top` query parameters to allow the client to specify an offset into the collection
and the number of results to return, respectively.

Note that when `top` specifies a value larger than the server-driven paging page size, the response will be paged accordingly.

## Conditional Requests

When designing an API, you will almost certainly have to manage how your resource is updated. For example, if your resource is a bank account, you will want to ensure that one transaction--say depositing money--does not overwrite a previous transaction.
Similarly, it could be very expensive to send a resource to a client. This could be because of its size, network conditions, or a myriad of other reasons.
Both of these scenarios can be accomplished with conditional requests, where the client specifies a _precondition_
for execution of a request, based on its last modification date or entity tag ("ETag").
An ETag identifies a 'version' or 'instance' of a resource and is computed by the service and returned in an `ETag` response header for GET or other operations on the resource.

### Cache Control

One of the more common uses for conditional requests is cache control. This is especially useful when resources are large in size, expensive to compute/calculate, or hard to reach (significant network latency).
A client can make a "conditional GET request" for the resource, with a precondition header that requests that
data be returned only when the version on the service does not match the ETag or last modified date in the header.
If there are no changes, then there is no need to return the resource, as the client already has the most recent version.

Implementing this strategy is relatively straightforward. First, you will return an `ETag` with a value that uniquely identifies the instance (or version) of the resource. The [Computing ETags](./Guidelines.md#computing-etags) section provides guidance on how to properly calculate the value of your `ETag`.
In these scenarios, when a request is made by the client an `ETag` header is returned, with a value that uniquely identifies that specific instance (or version) of the resource. The `ETag` value can then be sent in subsequent requests as part of the `If-None-Match` header.
This tells the service to compare the `ETag` that came in with the request, with the latest value that it has calculated. If the two values are the same, then it is not necessary to return the resource to the client--it already has it. If they are different, then the service will return the latest version of the resource, along with the updated `ETag` value in the header.

### Optimistic Concurrency

Optimistic concurrency is a strategy used in HTTP to avoid the "lost update" problem that can occur when multiple clients attempt to update a resource simultaneously.
Clients can use ETags returned by the service to specify a _precondition_ for the execution of an update, to ensure that the resource has not been updated since the client last observed it.
For example, the client can specify an `If-Match` header with the last ETag value received by the client in an update request.
The service processes the update only if the ETag value in the header matches the ETag of the current resource on the server.
By computing and returning ETags for your resources, you enable clients to avoid using a strategy where the "last write always wins."

## Returning String Offsets & Lengths (Substrings)

Some Azure services return substring offset & length values within a string. For example, the offset & length within a string to a name, email address, or phone number.
When a service response includes a string, the client's programming language deserializes that string into that language's internal string encoding. Below are the possible encodings and examples of languages that use each encoding:

| Encoding    | Example languages |
| -------- | ------- |
| UTF-8 | Go, Rust, Ruby, PHP |
| UTF-16 | JavaScript, Java, C# |
| CodePoint (UTF-32) | Python |

Because the service doesn't know in what language a client is written and what string encoding that language uses, the service can't return UTF-agnostic offset and length values that the client can use to index within the string. To address this, the service response must include offset & length values for all 3 possible encodings and then the client code must select the encoding required by its language's internal string encoding.

For example, if a service response needed to identify offset & length values for "name" and "email" substrings, the JSON response would look like this:

```text
{
  (... other properties not shown...)
  "fullString": "(...some string containing a name and an email address...)",
  "name": {
    "offset": {
      "utf8": 12,
      "utf16": 10,
      "codePoint": 4
    },
    "length": {
      "uft8": 10,
      "utf16": 8,
      "codePoint": 2
    }
  },
  "email": {
    "offset": {
      "utf8": 12,
      "utf16": 10,
      "codePoint": 4
    },
    "length": {
      "uft8": 10,
      "utf16": 8,
      "codePoint": 4
    }
  }
}
```

Then, the Go developer, for example, would get the substring containing the name using code like this:

```go
   var response := client.SomeMethodReturningJSONShownAbove(...)
   name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8]
```

The service must calculate the offset & length for all 3 encodings and return them because clients find it difficult working with Unicode encodings and how to convert from one encoding to another. In other words, we do this to simplify client development and ensure customer success when isolating a substring.

## Getting Help: The Azure REST API Stewardship Board
The Azure REST API Stewardship board is a collection of dedicated architects that are passionate about helping Azure service teams build interfaces that are intuitive, maintainable, consistent, and most importantly, delight our customers. Because APIs affect nearly all downstream decisions, you are encouraged to reach out to the Stewardship board early in the development process. These architects will work with you to apply these guidelines and identify any hidden pitfalls in your design.

### Typical Review Session
When engaging with the API REST Stewardship board, your working sessions will generally focus on three areas:
- Correctness - Your service should leverage the proper HTTP verbs, return codes, and respect the core constructs of a REST API, e.g. idempotency, that are standard throughout the industry.
- Consistency - Your services should look and behave as though they are natural part of the Azure platform.
- Well formed - Do your services adhere to REST and Azure standards, e.g. proper return codes, use of headers.
- Durable - Your APIs will grow and change over time and leveraging the common patterns described in this document will help you minimize your tech debt and move fast with confidence.

It was once said that "all roads lead to Rome." For cloud services, the equivalent might be that "all 'roads' start with your API." That could not be more true than at Microsoft, where client libraries, documentation, and many other artifacts all originate from the fundamental way you choose to expose your service.
With careful consideration at the outset of your development effort, the architectural stewardship of the API board, and the thoughtful application of these guidelines, you will be able to produce a consistent, well formed API that will delight our customers.


================================================
FILE: azure/Guidelines.md
================================================
# Microsoft Azure REST API Guidelines

<!-- cspell:ignore autorest, BYOS, etag, idempotency, maxpagesize, innererror, trippable, nextlink, condreq, etags -->
<!-- markdownlint-disable MD033 MD049 MD055 -->

<!--
Note to contributors: All guidelines now have an anchor tag to allow cross-referencing from associated tooling.
The anchor tags within a section using a common prefix to ensure uniqueness with anchor tags in other sections.
Please ensure that you add an anchor tag to any new guidelines that you add and maintain the naming convention.
-->

## History

<details>
  <summary>Expand change history</summary>

| Date        | Notes                                                          |
| ----------- | -------------------------------------------------------------- |
| 2025-Mar-28 | Added guidelines about JSON ID and null values                 |
| 2024-Mar-17 | Updated LRO guidelines                                         |
| 2024-Jan-17 | Added guidelines on returning string offsets & lengths         |
| 2023-May-12 | Explain service response for missing/unsupported `api-version` |
| 2023-Apr-21 | Update/clarify guidelines on POST method repeatability         |
| 2023-Apr-07 | Update/clarify guidelines on polymorphism                      |
| 2022-Sep-07 | Updated URL guidelines for DNS Done Right                      |
| 2022-Jul-15 | Update guidance on long-running operations                     |
| 2022-May-11 | Drop guidance on version discovery                             |
| 2022-Mar-29 | Add guidelines about using durations                           |
| 2022-Mar-25 | Update guideline for date values in headers to follow RFC 7231 |
| 2022-Feb-01 | Updated error guidance                                         |
| 2021-Sep-11 | Add long-running operations guidance                           |
| 2021-Aug-06 | Updated Azure REST Guidelines per Azure API Stewardship Board. |
| 2020-Jul-31 | Added service advice for initial versions                      |
| 2020-Mar-31 | 1st public release of the Azure REST API Guidelines            |

</details>

## Introduction

These guidelines apply to Azure service teams implementing _data plane_ APIs. They offer prescriptive guidance that Azure service teams MUST follow ensuring that customers have a great experience by designing APIs meeting these goals:
- Developer friendly via consistent patterns & web standards (HTTP, REST, JSON)
- Efficient & cost-effective
- Work well with SDKs in many programming languages
- Customers can create fault-tolerant apps by supporting retries/idempotency/optimistic concurrency
- Sustainable & versionable via clear API contracts with 2 requirements:
  1. Customer workloads must never break due to a service change
  2. Customers can adopt a version without requiring code changes

Technology and software is constantly changing and evolving, and as such, this is intended to be a living document. [Open an issue](https://github.com/microsoft/api-guidelines/issues/new/choose) to suggest a change or propose a new idea. Please read the [Considerations for Service Design](./ConsiderationsForServiceDesign.md) for an introduction to the topic of API design for Azure services. *For an existing GA'd service, don't change/break its existing API; instead, leverage these concepts for future APIs while prioritizing consistency within your existing service.*

*Note: If you are creating a management plane (ARM) API, please refer to the [Azure Resource Manager Resource Provider Contract](https://github.com/cloud-and-ai-microsoft/resource-provider-contract).*

### Prescriptive Guidance
This document offers prescriptive guidance labeled as follows:

:white_check_mark: **DO** adopt this pattern. If you feel you need an exception, contact the Azure HTTP/REST Stewardship Board **prior** to implementation.

:ballot_box_with_check: **YOU SHOULD** adopt this pattern. If not following this advice, you MUST disclose your reason during the Azure HTTP/REST Stewardship Board review.

:heavy_check_mark: **YOU MAY** consider this pattern if appropriate to your situation. No notification to the Azure HTTP/REST Stewardship Board is required.

:warning: **YOU SHOULD NOT** adopt this pattern. If not following this advice, you MUST disclose your reason during the Azure HTTP/REST Stewardship Board review.

:no_entry: **DO NOT** adopt this pattern. If you feel you need an exception, contact the Azure HTTP/REST Stewardship Board **prior** to implementation.

*If you feel you need an exception, or need clarity based on your situation, please contact the Azure HTTP/REST Stewardship Board **prior** to release of your API.*

## Building Blocks: HTTP, REST, & JSON
The Microsoft Azure Cloud platform exposes its APIs through the core building blocks of the Internet; namely HTTP, REST, and JSON. This section provides you with a general understanding of how these technologies should be applied when creating your service.

<a href="#http" name="http"></a>
### HTTP
Azure services must adhere to the HTTP specification, [RFC 7231](https://tools.ietf.org/html/rfc7231). This section further refines and constrains how service implementors should apply the constructs defined in the HTTP specification. It is therefore, important that you have a firm understanding of the following concepts:

- [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)
- [HTTP Request / Response Pattern](#http-request--response-pattern)
- [HTTP Query Parameters and Header Values](#http-query-parameters-and-header-values)

#### Uniform Resource Locators (URLs)

A Uniform Resource Locator (URL) is how developers access the resources of your service. Ultimately, URLs are how developers form a cognitive model of your service's resources.

<a href="#http-url-pattern" name="http-url-pattern">:white_check_mark:</a> **DO** use this URL pattern:
```text
https://<tenant>.<region>.<service>.<cloud>/<service-root>/<resource-collection>/<resource-id>
```

Where:
 | Field | Description
 | - | - |
 | tenant | Regionally-unique ID representing a tenant (used for isolation, billing, quota enforcement, lifetime of resources, etc.)
 | region | Identifies the tenant's selected region. This region string MUST match one of the strings in the "Name" column returned from running this Azure CLI's "az account list-locations -o table"
 | service | Name of the service (ex: blobstore, servicebus, directory, or management)
 | cloud | Cloud domain name, e.g. `azure.net` (see Azure CLI's "az cloud list")
 | service&#x2011;root | Service-specific path (ex: blobcontainer, myqueue)
 | resource&#x2011;collection | Name of the collection, unabbreviated, pluralized
 | resource&#x2011;id | Id of resource within the resource-collection. This MUST be the raw string/number/guid value with no quoting but properly escaped to fit in a URL segment.

<a href="#http-url-casing" name="http-url-casing">:white_check_mark:</a> **DO** use kebab-casing (preferred) or camel-casing for URL path segments. If the segment refers to a JSON field, use camel casing.

<a href="#http-url-length" name="http-url-length">:white_check_mark:</a> **DO** return `414-URI Too Long` if a URL exceeds 2083 characters

<a href="#http-url-case-sensitivity" name="http-url-case-sensitivity">:white_check_mark:</a> **DO** treat service-defined URL path segments as case-sensitive. If the passed-in case doesn't match what the service expects, the request **MUST** fail with a `404-Not found` HTTP return code.

Some customer-provided path segment values may be compared case-insensitivity if the abstraction they represent is normally compared with case-insensitivity. For example, a UUID path segment of 'c55f6b35-05f6-42da-8321-2af5099bd2a2' should be treated identical to 'C55F6B35-05F6-42DA-8321-2AF5099BD2A2'

<a href="#http-url-return-casing" name="http-url-return-casing">:white_check_mark:</a> **DO** ensure proper casing when returning a URL in an HTTP response header value or inside a JSON response body

<a href="#http-url-allowed-characters" name="http-url-allowed-characters">:white_check_mark:</a> **DO** restrict the characters in service-defined path segments to `0-9  A-Z  a-z  -  .  _  ~`, with `:` allowed only as described below to designate an action operation.

<a href="#http-url-allowed-characters-2" name="http-url-allowed-characters-2">:ballot_box_with_check:</a> **YOU SHOULD** restrict the characters allowed in user-specified path segments (i.e. path parameters values) to `0-9  A-Z  a-z  -  .  _  ~` (do not allow `:`).

<a href="#http-url-should-be-readable" name="http-url-should-be-readable">:ballot_box_with_check:</a> **YOU SHOULD** keep URLs readable; if possible, avoid UUIDs & %-encoding (ex: Cádiz is %-encoded as C%C3%A1diz)

<a href="#http-url-allowed-characters-3" name="http-url-allowed-characters-3">:heavy_check_mark:</a> **YOU MAY** use these other characters in the URL path but they will likely require %-encoding [[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.1)]: `/  ?  #  [  ]  @  !  $  &  '  (  )  *  +  ,  ;  =`

<a href="#http-direct-endpoints" name="http-direct-endpoints">:heavy_check_mark:</a> **YOU MAY** support a direct endpoint URL for performance/routing:
```text
https://<tenant>-<service-root>.<service>.<cloud>/...
```

Examples:
- Request URL: `https://blobstore.azure.net/contoso.com/account1/container1/blob2`
- Response header ([RFC 2557](https://datatracker.ietf.org/doc/html/rfc2557#section-4)): `content-location : https://contoso-dot-com-account1.blobstore.azure.net/container1/blob2`
- GUID format: `https://00000000-0000-0000-C000-000000000046-account1.blobstore.azure.net/container1/blob2`

<a href="#http-url-return-consistent-form" name="http-url-return-consistent-form">:white_check_mark:</a> **DO** return URLs in response headers/bodies in a consistent form regardless of the URL used to reach the resource. Either always a UUID for `<tenant>` or always a single verified domain.

<a href="#http-url-parameter-values" name="http-url-parameter-values">:heavy_check_mark:</a> **YOU MAY** use URLs as values
```text
https://api.contoso.com/items?url=https://resources.contoso.com/shoes/fancy
```

#### HTTP Request / Response Pattern
The HTTP Request / Response pattern dictates how your API behaves. For example: POST methods that create resources must be idempotent, GET method results may be cached, the If-Modified and ETag headers offer optimistic concurrency. The URL of a service, along with its request/response bodies, establishes the overall contract that developers have with your service. As a service provider, how you manage the overall request / response pattern should be one of the first implementation decisions you make.

Cloud applications embrace failure. Therefore, to enable customers to write fault-tolerant applications, _all_ service operations (including POST) **must** be idempotent. Implementing services in an idempotent manner, with an "exactly once" semantic, enables developers to retry requests without the risk of unintended consequences.

##### Exactly Once Behavior = Client Retries & Service Idempotency

<a href="#http-all-methods-idempotent" name="http-all-methods-idempotent">:white_check_mark:</a> **DO** ensure that _all_ HTTP methods are idempotent.

<a href="#http-use-put-or-patch" name="http-use-put-or-patch">:ballot_box_with_check:</a> **YOU SHOULD** use PUT or PATCH to create a resource as these HTTP methods are easy to implement, allow the customer to name their own resource, and are idempotent.

<a href="#http-post-must-be-idempotent" name="http-post-must-be-idempotent">:heavy_check_mark:</a> **YOU MAY** use POST to create a resource but you must make it idempotent and, of course, the response **MUST** return the URL of the created resource with a 201-Created. One way to make POST idempotent is to use the Repeatability-Request-ID & Repeatability-First-Sent headers (See [Repeatability of requests](#repeatability-of-requests)).

##### HTTP Return Codes

<a href="#http-success-status-codes" name="http-success-status-codes">:white_check_mark:</a> **DO** adhere to the return codes in the following table when the method completes synchronously and is successful:

Method | Description | Response Status Code
-------|-------------|---------------------
PATCH  | Create/Modify the resource with JSON Merge Patch | `200-OK`, `201-Created`
PUT    | Create/Replace the _whole_ resource | `200-OK`, `201-Created`
POST   | Create new resource (ID set by service) | `201-Created` with URL of created resource
POST   | Action | `200-OK`
GET    | Read (i.e. list) a resource collection | `200-OK`
GET    | Read the resource | `200-OK`
DELETE | Remove the resource | `204-No Content`\; avoid `404-Not Found`

<a href="#http-lro-status-code" name="http-lro-status-code">:white_check_mark:</a> **DO** return status code `202-Accepted` and follow the guidance in [Long-Running Operations & Jobs](#long-running-operations--jobs) when a PUT, POST, or DELETE method completes asynchronously.

<a href="#http-method-casing" name="http-method-casing">:white_check_mark:</a> **DO** treat method names as case sensitive and should always be in uppercase

<a href="#http-return-resource" name="http-return-resource">:white_check_mark:</a> **DO** return the state of the resource after a PUT, PATCH, POST, or GET operation with a `200-OK` or `201-Created`.

<a href="#http-delete-returns-204" name="http-delete-returns-204">:white_check_mark:</a> **DO** return a `204-No Content` without a resource/body for a DELETE operation (even if the URL identifies a resource that does not exist; do not return `404-Not Found`)

<a href="#http-post-action-returns-200" name="http-post-action-returns-200">:white_check_mark:</a> **DO** return a `200-OK` from a POST Action. Include a body in the response, even if it has not properties, to allow properties to be added in the future if needed.

<a href="#http-return-403-vs-404" name="http-return-403-vs-404">:white_check_mark:</a> **DO** return a `403-Forbidden` when the user does not have access to the resource _unless_ this would leak information about the existence of the resource that should not be revealed for security/privacy reasons, in which case the response should be `404-Not Found`. [Rationale: a `403-Forbidden` is easier to debug for customers, but should not be used if even admitting the existence of things could potentially leak customer secrets.]

<a href="#http-support-optimistic-concurrency" name="http-support-optimistic-concurrency">:white_check_mark:</a> **DO** support caching and optimistic concurrency by honoring the the `If-Match`, `If-None-Match`, if-modified-since, and if-unmodified-since request headers and by returning the ETag and last-modified response headers

#### HTTP Query Parameters and Header Values

<a href="#http-query-names-casing" name="http-query-names-casing">:white_check_mark:</a> **DO** use camel case for query parameter names.

Note: Certain legacy query parameter names use kebab-casing and are allowed only for backwards compatibility.

Because information in the service URL, as well as the request / response, are strings, there must be a predictable, well-defined scheme to convert strings to their corresponding values.

<a href="#http-parameter-validation" name="http-parameter-validation">:white_check_mark:</a> **DO** validate all query parameter and request header values and fail the operation with `400-Bad Request` if any value fails validation. Return an error response as described in the [Handling Errors](#handling-errors) section indicating what is wrong so customer can diagnose the issue and fix it themselves.

<a href="#http-parameter-serialization" name="http-parameter-serialization">:white_check_mark:</a> **DO** use the following table when translating strings:

Data type | Document that string must be
--------- | -------
Boolean   | true / false (all lowercase)
Integer   | -2<sup>53</sup>+1 to +2<sup>53</sup>-1 (for consistency with JSON limits on integers [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259))
Float     | [IEEE-754 binary64](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
String    | (Un)quoted?, max length, legal characters, case-sensitive, multiple delimiter
UUID      | 123e4567-e89b-12d3-a456-426614174000 (no {}s, hyphens, case-insensitive) [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)
Date/Time (Header) | Sun, 06 Nov 1994 08:49:37 GMT [RFC 7231, Section 7.1.1.1](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1)
Date/Time (Query parameter) | YYYY-MM-DDTHH:mm:ss.sssZ (with at most 3 digits of fractional seconds) [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339)
Byte array | Base-64 encoded, max length
Array      | One of a) a comma-separated list of values (preferred), or b) separate `name=value` parameter instances for each value of the array


The table below lists the headers most used by Azure services:

Header Key          | Applies to | Example
------------------- | ---------- | -------------
_authorization_     | Request    | Bearer eyJ0...Xd6j (Support Azure Active Directory)
_x-ms-useragent_    | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))
traceparent         | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))
tracecontext        | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))
accept              | Request    | application/json
If-Match            | Request    | "67ab43" or * (no quotes) (see [Conditional Requests](#conditional-requests))
If-None-Match       | Request    | "67ab43" or * (no quotes) (see [Conditional Requests](#conditional-requests))
If-Modified-Since   | Request    | Sun, 06 Nov 1994 08:49:37 GMT (see [Conditional Requests](#conditional-requests))
If-Unmodified-Since | Request    | Sun, 06 Nov 1994 08:49:37 GMT (see [Conditional Requests](#conditional-requests))
date                | Both       | Sun, 06 Nov 1994 08:49:37 GMT (see [RFC 7231, Section 7.1.1.2](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2))
_content-type_      | Both       | application/merge-patch+json
_content-length_    | Both       | 1024
_x-ms-request-id_   | Response   | 4227cdc5-9f48-4e84-921a-10967cb785a0
ETag                | Response   | "67ab43" (see [Conditional Requests](#conditional-requests))
last-modified       | Response   | Sun, 06 Nov 1994 08:49:37 GMT
_x-ms-error-code_   | Response   | (see [Handling Errors](#handling-errors))
_azure-deprecating_ | Response   | (see [Deprecating Behavior Notification](#deprecating-behavior-notification))
retry-after         | Response   | 180 (see [RFC 7231, Section 7.1.3](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3))

<a href="#http-header-support-standard-headers" name="http-header-support-standard-headers">:white_check_mark:</a> **DO** support all headers shown in _italics_

<a href="#http-header-names-casing" name="http-header-names-casing">:white_check_mark:</a> **DO** specify headers using kebab-casing

<a href="#http-header-names-case-sensitivity" name="http-header-names-case-sensitivity">:white_check_mark:</a> **DO** compare request header names using case-insensitivity

<a href="#http-header-values-case-sensitivity" name="http-header-values-case-sensitivity">:white_check_mark:</a> **DO** compare request header values using case-sensitivity if the header name requires it

<a href="#http-header-date-values" name="http-header-date-values">:white_check_mark:</a> **DO** accept date values in headers in HTTP-Date format and return date values in headers in the IMF-fixdate format as defined in [RFC 7231, Section 7.1.1.1](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1), e.g. "Sun, 06 Nov 1994 08:49:37 GMT".

Note: The RFC 7231 IMF-fixdate format is a "fixed-length and single-zone subset" of the RFC 1123 / RFC 5822 format, which means: a) year must be four digits, b) the seconds component of time is required, and c) the timezone must be GMT.

<a href="#http-header-request-id" name="http-header-request-id">:white_check_mark:</a> **DO** create an opaque value that uniquely identifies the request and return this value in the `x-ms-request-id` response header.

Your service should include the `x-ms-request-id` value in error logs so that users can submit support requests for specific failures using this value.

<a href="#http-allow-unrecognized-headers" name="http-allow-unrecognized-headers">:no_entry:</a> **DO NOT** fail a request that contains an unrecognized header. Headers may be added by API gateways or middleware and this must be tolerated

<a href="#http-no-x-custom-headers" name="http-no-x-custom-headers">:no_entry:</a> **DO NOT** use "x-" prefix for custom headers, unless the header already exists in production [[RFC 6648](https://datatracker.ietf.org/doc/html/rfc6648)].

**Additional References**
- [StackOverflow - Difference between http parameters and http headers](https://stackoverflow.com/questions/40492782)
- [Standard HTTP Headers](https://httpwg.org/specs/rfc7231.html#header.field.registration)
- [Why isn't HTTP PUT allowed to do partial updates in a REST API?](https://stackoverflow.com/questions/19732423/why-isnt-http-put-allowed-to-do-partial-updates-in-a-rest-api)

<a href="#rest" name="rest"></a>
### REpresentational State Transfer (REST)
REST is an architectural style with broad reach that emphasizes scalability, generality, independent deployment, reduced latency via caching, and security. When applying REST to your API, you define your service’s resources as a collections of items.
These are typically the nouns you use in the vocabulary of your service. Your service's [URLs](#uniform-resource-locators-urls) determine the hierarchical path developers use to perform CRUD (create, read, update, and delete) operations on resources. Note, it's important to model resource state, not behavior.
There are patterns, later in these guidelines, that describe how to invoke behavior on your service. See [this article in the Azure Architecture Center](https://docs.microsoft.com/azure/architecture/best-practices/api-design) for a more detailed discussion of REST API design patterns.

When designing your service, it is important to optimize for the developer using your API.

<a href="#rest-clear-naming" name="rest-clear-naming">:white_check_mark:</a> **DO** focus heavily on clear & consistent naming

<a href="#rest-paths-make-sense" name="rest-paths-make-sense">:white_check_mark:</a> **DO** ensure your resource paths make sense

<a href="#rest-simplify-operations" name="rest-simplify-operations">:white_check_mark:</a> **DO** simplify operations with few required query parameters & JSON fields

<a href="#rest-specify-string-value-constraints" name="rest-specify-string-value-constraints">:white_check_mark:</a> **DO** establish clear contracts for string values

<a href="#rest-use-standard-status-codes" name="rest-use-standard-status-codes">:white_check_mark:</a> **DO** use proper response codes/bodies so customer can diagnose their own problems and fix them without contacting Azure support or the service team

#### Resource Schema & Field Mutability

<a href="#rest-response-body-is-resource-schema" name="rest-response-body-is-resource-schema">:white_check_mark:</a> **DO** use the same JSON schema for PUT request/response, PATCH response, GET response, and POST request/response on a given URL path. The PATCH request schema should contain all the same fields with no required fields. This allows one SDK type for input/output operations and enables the response to be passed back in a request.

<a href="#rest-field-mutability" name="rest-field-mutability">:white_check_mark:</a> **DO** think about your resource's fields and how they are used:

Field Mutability | Service Request's behavior for this field
-----------------| -----------------------------------------
**Create** | Service honors field only when creating a resource. Minimize create-only fields so customers don't have to delete & re-create the resource.
**Update** | Service honors field when creating or updating a resource
**Read**   | Service returns this field in a response. If the client passed a read-only field, the service **MUST** fail the request unless the passed-in value matches the resource's current value

In addition to the above, a field may be "required" or "optional". A required field is guaranteed to always exist and will typically _not_ become a nullable field in a SDK's data structure. This allows customers to write code without performing a null-check.
Because of this, required fields can only be introduced in the 1st version of a service; it is a breaking change to introduce required fields in a later version. In addition, it is a breaking change to remove a required field or make an optional field required or vice versa.

<a href="#rest-flat-is-better-than-nested" name="rest-flat-is-better-than-nested">:white_check_mark:</a> **DO** make fields simple and maintain a shallow hierarchy.

<a href="#rest-get-returns-json-body" name="rest-get-returns-json-body">:white_check_mark:</a> **DO** use GET for resource retrieval and return JSON in the response body

<a href="#rest-patch-use-merge-patch" name="rest-patch-use-merge-patch">:white_check_mark:</a> **DO** create and update resources using PATCH [RFC 5789] with JSON Merge Patch [(RFC 7396)](https://datatracker.ietf.org/doc/html/rfc7396) request body.

<a href="#rest-put-for-create-or-replace" name="rest-put-for-create-or-replace">:white_check_mark:</a> **DO** use PUT with JSON for wholesale create/replace operations. **NOTE:** If a v1 client PUTs a resource; any fields introduced in V2+ should be reset to their default values (the equivalent to DELETE followed by PUT).

<a href="#rest-delete-resource" name="rest-delete-resource">:white_check_mark:</a> **DO** use DELETE to remove a resource.

<a href="#rest-fail-for-unknown-fields" name="rest-fail-for-unknown-fields">:white_check_mark:</a> **DO** fail an operation with `400-Bad Request` if the request is improperly-formed or if any JSON field name or value is not fully understood by the specific version of the service. Return an error response as described in [Handling errors](#handling-errors) indicating what is wrong so customer can diagnose the issue and fix it themselves.

<a href="#rest-secrets-allowed-in-post-response" name="rest-secrets-allowed-in-post-response">:heavy_check_mark:</a> **YOU MAY** return secret fields via POST **if absolutely necessary**.

<a href="#rest-no-secrets-in-get-response" name="rest-no-secrets-in-get-response">:no_entry:</a> **DO NOT** return secret fields via GET. For example, do not return `administratorPassword` in JSON.

<a href="#rest-no-computable-fields" name="rest-no-computable-fields">:no_entry:</a> **DO NOT** add fields to the JSON if the value is easily computable from other fields to avoid bloating the body.

##### Create / Update / Replace Processing Rules

<a href="#rest-put-patch-status-codes" name="rest-put-patch-status-codes">:white_check_mark:</a> **DO** follow the processing below to create/update/replace a resource:

When using this method | if this condition happens | use&nbsp;this&nbsp;response&nbsp;code
---------------------- | ------------------------- | ----------------------
PATCH/PUT | Any JSON field name/value not known/valid to the api-version | `400-Bad Request`
PATCH/PUT | Any Read field passed (client can't set Read fields) | `400-Bad Request`
| **If&nbsp;the&nbsp;resource&nbsp;does&nbsp;not&nbsp;exist** |
PATCH/PUT | Any mandatory Create/Update field missing | `400-Bad Request`
PATCH/PUT | Create resource using Create/Update fields | `201-Created`
| **If&nbsp;the&nbsp;resource&nbsp;already&nbsp;exists** |
PATCH | Any Create field doesn't match current value (allows retries) | `409-Conflict`
PATCH | Update resource using Update fields | `200-OK`
PUT | Any mandatory Create/Update field missing | `400-Bad Request`
PUT | Overwrite resource entirely using Create/Update fields | `200-OK`

#### Handling Errors
There are 2 kinds of errors:
- An error where you expect customer code to gracefully recover at runtime
- An error indicating a bug in customer code that is unlikely to be recoverable at runtime; the customer must just fix their code

<a href="#rest-error-code-header" name="rest-error-code-header">:white_check_mark:</a> **DO** return an `x-ms-error-code` response header with a string error code indicating what went wrong.

*NOTE: `x-ms-error-code` values are part of your API contract (because customer code is likely to do comparisons against them) and cannot change in the future.*

<a href="#rest-error-code-enum" name="rest-error-code-enum">:heavy_check_mark:</a> **YOU MAY** implement the `x-ms-error-code` values as an enum with `"modelAsString": true` because it's possible add new values over time.  In particular, it's only a breaking change if the same conditions result in a *different* top-level error code.

<a href="#rest-add-codes-in-new-api-version" name="rest-add-codes-in-new-api-version">:warning:</a> **YOU SHOULD NOT** add new top-level error codes to an existing API without bumping the service version.

<a href="#rest-descriptive-error-code-values" name="rest-descriptive-error-code-values">:white_check_mark:</a> **DO** carefully craft unique `x-ms-error-code` string values for errors that are recoverable at runtime.  Reuse common error codes for usage errors that are not recoverable.

<a href="#rest-error-code-grouping" name="rest-error-code-grouping">:heavy_check_mark:</a> **YOU MAY** group common customer code errors into a few `x-ms-error-code` string values.

<a href="#rest-error-code-header-and-body-match" name="rest-error-code-header-and-body-match">:white_check_mark:</a> **DO** ensure that the top-level error's `code` value is identical to the `x-ms-error-code` header's value.

<a href="#rest-error-response-body-structure" name="rest-error-response-body-structure">:white_check_mark:</a> **DO** provide a response body with the following structure:

**ErrorResponse** : Object

Property | Type | Required | Description
-------- | ---- | :------: | -----------
`error` | ErrorDetail | ✔ | The top-level error object whose `code` matches the `x-ms-error-code` response header

**ErrorDetail** : Object

Property | Type | Required | Description
-------- | ---- | :------: | -----------
`code` | String | ✔ | One of a server-defined set of error codes.
`message` | String | ✔ | A human-readable representation of the error.
`target` | String |  | The target of the error.
`details` | ErrorDetail[] |  | An array of details about specific errors that led to this reported error.
`innererror` | InnerError |  | An object containing more specific information than the current object about the error.
_additional properties_ |   | | Additional properties that can be useful when debugging.

**InnerError** : Object

Property | Type | Required | Description
-------- | ---- | :------: | -----------
`code` | String |  | A more specific error code than was provided by the containing error.
`innererror` | InnerError |  | An object containing more specific information than the current object about the error.

Example:
```json
{
  "error": {
    "code": "InvalidPasswordFormat",
    "message": "Human-readable description",
    "target": "target of error",
    "innererror": {
      "code": "PasswordTooShort",
      "minLength": 6,
    }
  }
}
```

<a href="#rest-document-error-code-values" name="rest-document-error-code-values">:white_check_mark:</a> **DO** document the service's top-level error code strings; they are part of the API contract.

<a href="#rest-error-non-api-contract-fields" name="rest-error-non-api-contract-fields">:heavy_check_mark:</a> **YOU MAY** treat the other fields as you wish as they are _not_ considered part of your service's API contract and customers should not take a dependency on them or their value. They exist to help customers self-diagnose issues.

<a href="#rest-error-additional-properties-allowed" name="rest-error-additional-properties-allowed">:heavy_check_mark:</a> **YOU MAY** add additional properties for any data values in your error message so customers don't resort to parsing your error message.  For example, an error with `"message": "A maximum of 16 keys are allowed per account."` might also add a `"maximumKeys": 16` property.  This is not part of your API contract and should only be used for diagnosing problems.

*Note: Do not use this mechanism to provide information developers need to rely on in code (ex: the error message can give details about why you've been throttled, but the `Retry-After` should be what developers rely on to back off).*

<a href="#rest-error-use-default-response" name="rest-error-use-default-response">:warning:</a> **YOU SHOULD NOT** document specific error status codes in your OpenAPI/Swagger spec unless the "default" response cannot properly describe the specific error response (e.g. body schema is different).

<a href="#json" name="json"></a>
### JSON

<a href="#json-field-name-casing" name="json-field-name-casing">:white_check_mark:</a> **DO** use camel case for all JSON field names. Do not upper-case acronyms; use camel case.

<a href="#json-field-names-case-sensitivity" name="json-field-names-case-sensitivity">:white_check_mark:</a> **DO** treat JSON field names with case-sensitivity.

<a href="#json-field-values-case-sensitivity" name="json-field-values-case-sensitivity">:white_check_mark:</a> **DO** treat JSON field values with case-sensitivity. There may be some exceptions but avoid if at all possible.

<a href="#json-field-values-id" name="json-field-values-ids">:white_check_mark:</a> **DO** treat JSON field value representing a unique ID as an opaque string value and compare them with case-sensitivity. For example, IDs are frequently [UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier), [CUIDs](https://github.com/paralleldrive/cuid2), [Nano ID](https://blog.openapihub.com/en-us/what-is-nano-id-its-difference-from-uuid-as-unique-identifiers/), or other formats. The choice of ID format is a service implementation detail. Customer code should only ever need to get, store, and send these values and should never perform any other kind of parsing or interpretation of ID values.

Services, and the clients that access them, may be written in multiple languages. To ensure interoperability, JSON establishes the "lowest common denominator" type system, which is always sent over the wire as UTF-8 bytes. This system is very simple and consists of three types:

 Type | Description
 ---- | -----------
 Boolean | true/false (always lowercase)
 Number  | Signed floating point (IEEE-754 binary64; int range: -2<sup>53</sup>+1 to +2<sup>53</sup>-1)
 String  | Used for everything else

<a href="#json-null-response-values" name="json-null-response-values">:no_entry:</a> **DO NOT** send JSON fields with a null value from the service to the client. Instead, the service should just not send this field at all (this reduces payload size). Semantically, Azure services treat a missing field and a field with a value of null as identical. 

<a href="#json-null-request-values" name="json-null-resquest-values">:white_check_mark:</a> **DO** accept JSON fields with a null value only for a PATCH operation with a JSON Merge Patch payload. A field with a value of null instructs the service to delete the field. If the field cannot be deleted, then return 400-BadRequest, else return the resource with the deleted field missing from the response payload (see bullet above).

<a href="#json-integer-values" name="json-integer-values">:white_check_mark:</a> **DO** use integers within the acceptable range of JSON number.

<a href="#json-specify-string-constraints" name="json-specify-string-constraints">:white_check_mark:</a> **DO** establish a well-defined contract for the format of strings. For example, determine minimum length, maximum length, legal characters, case-(in)sensitive comparisons, etc. Where possible, use standard formats, e.g. RFC 3339 for date/time.

<a href="#json-use-standard-string-formats" name="json-use-standard-string-formats">:white_check_mark:</a> **DO** use strings formats that are well-known and easily parsable/formattable by many programming languages, e.g. RFC 3339 for date/time.

<a href="#json-should-be-round-trippable" name="json-should-be-round-trippable">:white_check_mark:</a> **DO** ensure that information exchanged between your service and any client is "round-trippable" across multiple programming languages.

<a href="#json-date-time-is-rfc3339" name="json-date-time-is-rfc3339">:white_check_mark:</a> **DO** use [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) for date/time.

<a href="#json-durations-use-fixed-time-intervals" name="json-durations-use-fixed-time-intervals">:white_check_mark:</a> **DO** use a fixed time interval to express durations e.g., milliseconds, seconds, minutes, days, etc., and include the time unit in the property name e.g., `backupTimeInMinutes` or `ttlSeconds`.

<a href="#json-rfc3339-time-intervals-allowed" name="json-rfc3339-time-intervals-allowed">:heavy_check_mark:</a> **YOU MAY** use [RFC 3339 time intervals](https://wikipedia.org/wiki/ISO_8601#Durations) only when users must be able to specify a time interval that may change from month to month or year to year e.g., "P3M" represents 3 months no matter how many days between the start and end dates, or "P1Y" represents 366 days on a leap year. The value must be round-trippable.

<a href="#json-uuid-is-rfc4412" name="json-uuid-is-rfc4412">:white_check_mark:</a> **DO** use [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) for UUIDs.

<a href="#json-may-nest-for-grouping" name="json-may-nest-for-grouping">:heavy_check_mark:</a> **YOU MAY** use JSON objects to group sub-fields together.

<a href="#json-use-arrays-for-ordering" name="json-use-arrays-for-ordering">:heavy_check_mark:</a> **YOU MAY** use JSON arrays if maintaining an order of values is required. Avoid arrays in other situations since arrays can be difficult and inefficient to work with, especially with JSON Merge Patch where the entire array needs to be read prior to any operation being applied to it.

<a href="#json-prefer-objects-over-arrays" name="json-prefer-objects-over-arrays">:ballot_box_with_check:</a> **YOU SHOULD** use JSON objects instead of arrays whenever possible.

#### Enums & SDKs (Client libraries)
It is common for strings to have an explicit set of values. These are often reflected in the OpenAPI definition as enumerations. These are extremely useful for developer tooling, e.g. code completion, and client library generation.

However, it is not uncommon for the set of values to grow over the life of a service. For this reason, Microsoft's tooling uses the concept of an "extensible enum," which indicates that the set of values should be treated as only a _partial_ list.
This indicates to client libraries and customers that values of the enumeration field should be effectively treated as strings and that undocumented value may returned in the future. This enables the set of values to grow over time while ensuring stability in client libraries and customer code.

<a href="#json-use-extensible-enums" name="json-use-extensible-enums">:ballot_box_with_check:</a> **YOU SHOULD** use extensible enumerations unless you are positive that the symbol set will NEVER change over time.

<a href="#json-document-extensible-enums" name="json-document-extensible-enums">:white_check_mark:</a> **DO** document to customers that new values may appear in the future so that customers write their code today expecting these new values tomorrow.

<a href="#json-return-extensible-enum-value" name="json-return-extensible-enum-value">:heavy_check_mark:</a> **YOU MAY** return a value for an extensible enum that is not one of the values defined for the api-version specified in the request.

<a href="#json-accept-extensible-enum-value" name="json-accept-extensible-enum-value">:warning:</a> **YOU SHOULD NOT** accept a value for an extensible enum that is not one of the values defined for the api-version specified in the request.

<a href="#json-removing-enum-value-is-breaking" name="json-removing-enum-value-is-breaking">:no_entry:</a> **DO NOT** remove values from your enumeration list as this breaks customer code.

#### Polymorphic types

Polymorphism types in REST APIs refers to the possibility to use the same property of a request or response to have similar but different shapes. This is commonly expressed as a `oneOf` in JsonSchema or OpenAPI. In order to simplify how to determine which specific type a given request or response payload corresponds to, Azure requires the use of an explicit discriminator field.

Note: Polymorphic types can make your service more difficult for nominally typed languages to consume. See the corresponding section in the [Considerations for service design](./ConsiderationsForServiceDesign.md#avoid-surprises) for more information.

<a href="#json-use-discriminator-for-polymorphism" name="json-use-discriminator-for-polymorphism">:white_check_mark:</a> **DO** define a discriminator field indicating the kind of the resource and include any kind-specific fields in the body.

Below is an example of JSON for a Rectangle and Circle with a discriminator field named `kind`:

**Rectangle**
```json
{
   "kind": "rectangle",
   "x": 100,
   "y": 50,
   "width": 10,
   "length": 24,
   "fillColor": "Red",
   "lineColor": "White",
   "subscription": {
      "kind": "free"
   }
}
```

**Circle**
```json
{
   "kind": "circle",
   "x": 100,
   "y": 50,
   "radius": 10,
   "fillColor": "Green",
   "lineColor": "Black",
   "subscription": {
      "kind": "paid",
      "expiration": "2024",
      "invoice": "123456"
   }
}
```
Both Rectangle and Circle have common fields: `kind`, `fillColor`, `lineColor`, and `subscription`. A Rectangle also has `x`, `y`, `width`, and `length` while a Circle has `x`, `y`, and `radius`. The `subscription` is a nested polymorphic type. A `free` subscription has no additional fields and a `paid` subscription has `expiration` and `invoice` fields.

The [Azure Naming Guidelines](./ConsiderationsForServiceDesign.md#common-names) recommend that the discriminator field be named `kind`.

<a href="#json-polymorphism-kind-extensible" name="json-polymorphism-kind-extensible">:ballot_box_with_check:</a> **YOU SHOULD** define the discriminator field of a polymorphic type to be an extensible enum.

<a href="#json-polymorphism-kind-immutable" name="json-polymorphism-kind-immutable">:warning:</a> **YOU SHOULD NOT** allow an update (patch) to change the discriminator field of a polymorphic type.

<a href="#json-polymorphism-versioning" name="json-polymorphism-versioning">:warning:</a> **YOU SHOULD NOT** return properties of a polymorphic type that are not defined for the api-version specified in the request.

<a href="#json-polymorphism-arrays" name="json-polymorphism-arrays">:warning:</a> **YOU SHOULD NOT** have a property of an updatable resource whose value is an array of polymorphic objects.

Updating an array property with JSON merge-patch is not version-resilient if the array contains polymorphic types.

## Common API Patterns

<a href="#actions" name="actions"></a>
### Performing an Action
The REST specification is used to model the state of a resource, and is primarily intended to handle CRUD (Create, Read, Update, Delete) operations. However, many services require the ability to perform an action on a resource, e.g. getting the thumbnail of an image or rebooting a VM.  It is also sometimes useful to perform an action on a collection.

<a href="#actions-url-pattern-for-resource-action" name="actions-url-pattern-for-resource-action">:ballot_box_with_check:</a> **YOU SHOULD** pattern your URL like this to perform an action on a resource
**URL Pattern**
```text
https://.../<resource-collection>/<resource-id>:<action>?<input parameters>
```

**Example**
```text
https://.../users/Bob:grant?access=read
```

<a href="#actions-url-pattern-for-collection-action" name="actions-url-pattern-for-collection-action">:ballot_box_with_check:</a> **YOU SHOULD** pattern your URL like this to perform an action on a collection
**URL Pattern**
```text
https://.../<resource-collection>:<action>?<input parameters>
```

**Example**
```text
https://.../users:grant?access=read
```

Note: To avoid potential collision of actions and resource ids, you should disallow the use of the ":" character in resource ids.

<a href="#actions-use-post-method" name="actions-use-post-method">:white_check_mark:</a> **DO** use a POST operation for any action on a resource or collection.

<a href="#actions-support-repeatability-headers" name="actions-support-repeatability-headers">:white_check_mark:</a> **DO** support the Repeatability-Request-ID & Repeatability-First-Sent request headers if the action needs to be idempotent if retries occur.

<a href="#actions-synchronous-success-status-code" name="actions-synchronous-success-status-code">:white_check_mark:</a> **DO** return a `200-OK` when the action completes synchronously and successfully.

<a href="#actions-action-name-is-verb" name="actions-action-name-is-verb">:ballot_box_with_check:</a> **YOU SHOULD** use a verb as the `<action>` component of the path.

<a href="#actions-no-actions-for-crud" name="actions-no-actions-for-crud">:no_entry:</a> **DO NOT** use an action operation when the operation behavior could reasonably be defined as one of the standard REST Create, Read, Update, Delete, or List operations.

<a href="#collections" name="collections"></a>
### Collections
<a href="#collections-response-is-object" name="collections-response-is-object">:white_check_mark:</a> **DO** structure the response to a list operation as an object with a top-level array field containing the set (or subset) of resources.

<a href="#collections-support-server-driven-paging" name="collections-support-server-driven-paging">:ballot_box_with_check:</a> **YOU SHOULD** support paging today if there is ever a chance in the future that the number of items can grow to be very large.

NOTE: It is a breaking change to add paging in the future

<a href="#collections-use-get-method" name="collections-use-get-method">:heavy_check_mark:</a> **YOU MAY** expose an operation that lists your resources by supporting a GET method with a URL to a resource-collection (as opposed to a resource-id).

**Example Response Body**
```json
{
    "value": [
       { "id": "Item 01", "etag": "\"abc\"", "price": 99.95, "size": "Medium" },
       { … },
       { … },
       { "id": "Item 99", "etag": "\"def\"", "price": 59.99, "size": "Large" }
    ],
    "nextLink": "{opaqueUrl}"
 }
```

<a href="#collections-items-have-id-and-etag" name="collections-items-have-id-and-etag">:white_check_mark:</a> **DO** include the _id_ field and _etag_ field (if supported) for each item as this allows the customer to modify the item in a future operation. Note that the etag field _must_ have escaped quotes embedded within it; for example, "\"abc\"" or W/"\"abc\"".

<a href="#collections-document-pagination-reliability" name="collections-document-pagination-reliability">:white_check_mark:</a> **DO** clearly document that resources may be skipped or duplicated across pages of a paginated collection unless the operation has made special provisions to prevent this (like taking a time-expiring snapshot of the collection).

<a href="#collections-include-nextlink-for-more-results" name="collections-include-nextlink-for-more-results">:white_check_mark:</a> **DO** return a `nextLink` field with an absolute URL that the client can GET in order to retrieve the next page of the collection.

Note: The service is responsible for performing any URL-encoding required on the `nextLink` URL.

<a href="#collections-nextlink-includes-all-query-params" name="collections-nextlink-includes-all-query-params">:white_check_mark:</a> **DO** include any query parameters required by the service in `nextLink`, including `api-version`.

<a href="#collections-response-array-name" name="collections-response-array-name">:ballot_box_with_check:</a> **YOU SHOULD** use `value` as the name of the top-level array field unless a more appropriate name is available.

<a href="#collections-no-nextlink-on-last-page" name="collections-no-nextlink-on-last-page">:no_entry:</a> **DO NOT** return the `nextLink` field at all when returning the last page of the collection.

<a href="#collections-nextlink-value-never-null" name="collections-nextlink-value-never-null">:no_entry:</a> **DO NOT** return the `nextLink` field with a value of null.

<a href="#collections-avoid-count-property" name="collections-avoid-count-property">:warning:</a> **YOU SHOULD NOT** return a `count` of all objects in the collection as this may be expensive to compute.

#### Query options

<a href="#collections-query-options" name="collections-query-options">:heavy_check_mark:</a> **YOU MAY** support the following query parameters allowing customers to control the list operation:

Parameter&nbsp;name | Type | Description
------------------- | ---- | -----------
`filter`       | string            | an expression on the resource type that selects the resources to be returned
`orderby`      | string&nbsp;array | a list of expressions that specify the order of the returned resources
`skip`         | integer           | an offset into the collection of the first resource to be returned
`top`          | integer           | the maximum number of resources to return from the collection
`maxpagesize`  | integer           | the maximum number of resources to include in a single response
`select`       | string&nbsp;array | a list of field names to be returned for each resource
`expand`       | string&nbsp;array | a list of the related resources to be included in line with each resource

<a href="#collections-error-on-unknown-parameter" name="collections-error-on-unknown-parameter">:white_check_mark:</a> **DO** return an error if the client specifies any parameter not supported by the service.

<a href="#collections-parameter-names-case-sensitivity" name="collections-parameter-names-case-sensitivity">:white_check_mark:</a> **DO** treat these query parameter names as case-sensitive.

<a href="#collections-select-expand-ordering" name="collections-select-expand-ordering">:white_check_mark:</a> **DO** apply `select` or `expand` options after applying all the query options in the table above.

<a href="#collections-query-options-ordering" name="collections-query-options-ordering">:white_check_mark:</a> **DO** apply the query options to the collection in the order shown in the table above.

<a href="#collections-query-options-no-dollar-sign" name="collections-query-options-no-dollar-sign">:no_entry:</a> **DO NOT** prefix any of these query parameter names with "$" (the convention in the [OData standard](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_QueryingCollections)).

#### filter

<a href="#collections-filter-param" name="collections-filter-param">:heavy_check_mark:</a> **YOU MAY** support filtering of the results of a list operation with the `filter` query parameter.

The value of the `filter` query parameter is an expression involving the fields of the resource that produces a Boolean value. This expression is evaluated for each resource in the collection and only items where the expression evaluates to true are included in the response.

<a href="#collections-filter-behavior" name="collections-filter-behavior">:white_check_mark:</a> **DO** omit all resources from the collection for which the filter expression evaluates to false or to null, or references properties that are unavailable due to permissions.

Example: return all Products whose Price is less than $10.00

```text
GET https://api.contoso.com/products?filter=price lt 10.00
```

##### filter operators

:heavy_check_mark: **YOU MAY** support the following operators in filter expressions:

Operator                 | Description           | Example
--------------------     | --------------------- | -----------------------------------------------------
**Comparison Operators** |                       |
eq                       | Equal                 | city eq 'Redmond'
ne                       | Not equal             | city ne 'London'
gt                       | Greater than          | price gt 20
ge                       | Greater than or equal | price ge 10
lt                       | Less than             | price lt 20
le                       | Less than or equal    | price le 100
**Logical Operators**    |                       |
and                      | Logical and           | price le 200 and price gt 3.5
or                       | Logical or            | price le 3.5 or price gt 200
not                      | Logical negation      | not price le 3.5
**Grouping Operators**   |                       |
( )                      | Precedence grouping   | (priority eq 1 or city eq 'Redmond') and price gt 100

<a href="#collections-filter-unknown-operator" name="collections-filter-unknown-operator">:white_check_mark:</a> **DO** respond with an error message as defined in the [Handling Errors](#handling-errors) section if a client includes an operator in a filter expression that is not supported by the operation.

<a href="#collections-filter-operator-ordering" name="collections-filter-operator-ordering">:white_check_mark:</a> **DO** use the following operator precedence for supported operators when evaluating filter expressions. Operators are listed by category in order of precedence from highest to lowest. Operators in the same category have equal precedence and should be evaluated left to right:

| Group           | Operator | Description
| ----------------|----------|------------
| Grouping        | ( )      | Precedence grouping   |
| Unary           | not      | Logical Negation      |
| Relational      | gt       | Greater Than          |
|                 | ge       | Greater than or Equal |
|                 | lt       | Less Than             |
|                 | le       | Less than or Equal    |
| Equality        | eq       | Equal                 |
|                 | ne       | Not Equal             |
| Conditional AND | and      | Logical And           |
| Conditional OR  | or       | Logical Or            |

<a href="#collections-filter-functions" name="collections-filter-functions">:heavy_check_mark:</a> **YOU MAY** support orderby and filter functions such as concat and contains. For more information, see [odata Canonical Functions](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31360979).

##### Operator examples
The following examples illustrate the use and semantics of each of the logical operators.

Example: all products with a name equal to 'Milk'

```text
GET https://api.contoso.com/products?filter=name eq 'Milk'
```

Example: all products with a name not equal to 'Milk'

```text
GET https://api.contoso.com/products?filter=name ne 'Milk'
```

Example: all products with the name 'Milk' that also have a price less than 2.55:

```text
GET https://api.contoso.com/products?filter=name eq 'Milk' and price lt 2.55
```

Example: all products that either have the name 'Milk' or have a price less than 2.55:

```text
GET https://api.contoso.com/products?filter=name eq 'Milk' or price lt 2.55
```

Example: all products that have the name 'Milk' or 'Eggs' and have a price less than 2.55:

```text
GET https://api.contoso.com/products?filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55
```

#### orderby

<a href="#collections-orderby-param" name="collections-orderby-param">:heavy_check_mark:</a> **YOU MAY** support sorting of the results of a list operation with the `orderby` query parameter.
*NOTE: It is unusual for a service to support `orderby` because it is very expensive to implement as it requires sorting the entire large collection before being able to return any results.*

The value of the `orderby` parameter is a comma-separated list of expressions used to sort the items.
A special case of such an expression is a property path terminating on a primitive property.

Each expression in the `orderby` parameter value may include the suffix "asc" for ascending or "desc" for descending, separated from the expression by one or more spaces.

<a href="#collections-orderby-ordering" name="collections-orderby-ordering">:white_check_mark:</a> **DO** sort the collection in ascending order on an expression if "asc" or "desc" is not specified.

<a href="#collections-orderby-null-ordering" name="collections-orderby-null-ordering">:white_check_mark:</a> **DO** sort NULL values as "less than" non-NULL values.

<a href="#collections-orderby-behavior" name="collections-orderby-behavior">:white_check_mark:</a> **DO** sort items by the result values of the first expression, and then sort items with the same value for the first expression by the result value of the second expression, and so on.

<a href="#collections-orderby-inherent-sort-order" name="collections-orderby-inherent-sort-order">:white_check_mark:</a> **DO** use the inherent sort order for the type of the field. For example, date-time values should be sorted chronologically and not alphabetically.

<a href="#collections-orderby-unsupported-field" name="collections-orderby-unsupported-field">:white_check_mark:</a> **DO** respond with an error message as defined in the [Handling Errors](#handling-errors) section if the client requests sorting by a field that is not supported by the operation.

For example, to return all people sorted by name in ascending order:
```text
GET https://api.contoso.com/people?orderby=name
```

For example, to return all people sorted by name in descending order and a secondary sort order of hireDate in ascending order.
```text
GET https://api.contoso.com/people?orderby=name desc,hireDate
```

Sorting MUST compose with filtering such that:
```text
GET https://api.contoso.com/people?filter=name eq 'david'&orderby=hireDate
```
will return all people whose name is David sorted in ascending order by hireDate.

##### Considerations for sorting with pagination

<a href="#collections-consistent-options-with-pagination" name="collections-consistent-options-with-pagination">:white_check_mark:</a> **DO** use the same filtering options and sort order for all pages of a paginated list operation response.

##### skip
<a href="#collections-skip-param-definition" name="collections-skip-param-definition">:white_check_mark:</a> **DO** define the `skip` parameter as an integer with a default and minimum value of 0.

<a href="#collections-skip-param" name="collections-skip-param">:heavy_check_mark:</a> **YOU MAY** allow clients to pass the `skip` query parameter to specify an offset into collection of the first resource to be returned.
##### top

<a href="#collections-" name="collections-"></a>
<a href="#collections-top-param" name="collections-top-param">:heavy_check_mark:</a> **YOU MAY** allow clients to pass the `top` query parameter to specify the maximum number of resources to return from the collection.

If supporting `top`:
:white_check_mark: **DO** define the `top` parameter as an integer with a minimum value of 1. If not specified, `top` has a default value of infinity.

<a href="#collections-top-behavior" name="collections-top-behavior">:white_check_mark:</a> **DO** return the collection's `top` number of resources (if available), starting from `skip`.

##### maxpagesize

<a href="#collections-maxpagesize-param" name="collections-maxpagesize-param">:heavy_check_mark:</a> **YOU MAY** allow clients to pass the `maxpagesize` query parameter to specify the maximum number of resources to include in a single page response.

<a href="#collections-maxpagesize-definition" name="collections-maxpagesize-definition">:white_check_mark:</a> **DO** define the `maxpagesize` parameter as an optional integer with a default value appropriate for the collection.

<a href="#collections-maxpagesize-might-return-fewer" name="collections-maxpagesize-might-return-fewer">:white_check_mark:</a> **DO** make clear in documentation of the `maxpagesize` parameter that the operation may choose to return fewer resources than the value specified.

<a href="#versioning" name="versioning"></a>
### API Versioning

Azure services need to change over time. However, when changing a service, there are 2 requirements:
 1. Already-running customer workloads must not break due to a service change
 2. Customers can adopt a new service version without requiring any code changes (Of course, the customer must modify code to leverage any new service features.)

*NOTE: the [Azure Breaking Change Policy](http://aka.ms/AzBreakingChangesPolicy) has tables (section 5) describing what kinds of changes are considered breaking. Breaking changes are allowable (due to security/compliance/etc.) if approved by the [Azure Breaking Change Reviewers](mailto:azbreakchangereview@microsoft.com) but only following ample communication to customers and a lengthy deprecation period.*

<a href="#versioning-review-required" name="versioning-review-required">:white_check_mark:</a> **DO** review any API changes with the Azure API Stewardship Board

Clients specify the version of the API to be used in every request to the service, even requests to an `Operation-Location` or `nextLink` URL returned by the service.

<a href="#versioning-api-version-query-param" name="versioning-api-version-query-param">:white_check_mark:</a> **DO** use a required query parameter named `api-version` on every operation for the client to specify the API version.

<a href="#versioning-date-based-versioning" name="versioning-date-based-versioning">:white_check_mark:</a> **DO** use `YYYY-MM-DD` date values, with a `-preview` suffix for preview versions, as the valid values for `api-version`.

<a href="#versioning-api-version-missing" name="versioning-api-version-missing">:white_check_mark:</a> **DO** return HTTP 400 with error code "MissingApiVersionParameter" and message "The api-version query parameter (?api-version=) is required for all requests" if client omits the `api-version` query parameter.

<a href="#versioning-api-version-unsupported" name="versioning-api-version-unsupported">:white_check_mark:</a> **DO** return HTTP 400 with error code "UnsupportedApiVersionValue" and message "Unsupported api-version '{0}'. The supported api-versions are '{1}'." if client passes an `api-version` value unrecognized by the service. For the supported api-versions, just list all the stable versions still supported by the service and just the latest public preview version (if any).

```text
PUT https://service.azure.com/users/Jeff?api-version=2021-06-04
```

<a href="#versioning-use-later-date" name="versioning-use-later-date">:white_check_mark:</a> **DO** use a later date for each new preview version

When releasing a new preview, the service team may completely retire any previous preview versions after giving customers at least 90 days to upgrade their code

<a href="#versioning-no-breaking-changes" name="versioning-no-breaking-changes">:no_entry:</a> **DO NOT** introduce any breaking changes into the service.

<a href="#versioning-no-version-in-path" name="versioning-no-version-in-path">:no_entry:</a> **DO NOT** include a version number segment in any operation path.

<a href="#versioning-use-later-date-2" name="versioning-use-later-date-2">:no_entry:</a> **DO NOT** use the same date when transitioning from a preview API to a GA API. If the preview `api-version` is '2021-06-04-preview', the GA version of the API **must be** a date later than 2021-06-04

<a href="#versioning-preview-goes-ga-within-one-year" name="versioning-preview-goes-ga-within-one-year">:no_entry:</a> **DO NOT** keep a preview feature in preview for more than 1 year; it must go GA (or be removed) within 1 year after introduction.

#### Use Extensible Enums

While removing a value from an enum is a breaking change, adding value to an enum can be handled with an _extensible enum_.  An extensible enum is a string value that has been marked with a special marker - setting `modelAsString` to true within an `x-ms-enum` block.  For example:

```json
"createdByType": {
   "type": "string",
   "description": "The type of identity that created the resource.",
   "enum": [
      "User",
      "Application",
      "ManagedIdentity",
      "Key"
   ],
   "x-ms-enum": {
      "name": "createdByType",
      "modelAsString": true
   }
}
```

<a href="#versioning-use-extensible-enums" name="versioning-use-extensible-enums">:ballot_box_with_check:</a> **YOU SHOULD** use extensible enums unless you are positive that the symbol set will **NEVER** change over time.

<a href="#deprecation" name="deprecation"></a>
### Deprecating Behavior Notification

When the [API Versioning](#api-versioning) guidance above cannot be followed and the [Azure Breaking Change Reviewers](mailto:azbreakchangereview@microsoft.com) approve a breaking change to a specific API version it must be communicated to its callers. The API version that is being deprecated must add the `azure-deprecating` response header with a semicolon-delimited string notifying the caller what is being deprecated, when it will no longer function, and a URL linking to more information such as what new operation they should use instead.

The purpose is to inform customers (when debugging/logging responses) that they must take action to modify their call to the service's operation and use a newer API version or their call will soon stop working entirely. It is not expected that client code will examine/parse this header's value in any way; it is purely informational to a human being. The string is _not_ part of an API contract (except for the semi-colon delimiters) and may be changed/improved at any time without incurring a breaking change.

<a href="#deprecation-header" name="deprecation-header">:white_check_mark:</a> **DO** include the `azure-deprecating` header in the operation's response _only if_ the operation will stop working in the future and the client _must take_ action in order for it to keep working.
> NOTE: We do not want to scare customers with this header.

<a href="#deprecation-header-value" name="deprecation-header-value">:white_check_mark:</a> **DO** make the header's value a semicolon-delimited string indicating a set of deprecations where each one indicates what is deprecating, when it is deprecating, and a URL to more information.

Deprecations should use the following pattern:
```text
<description> will retire on <date> (<url>)
```

Multiple deprecations are allowed, semicolon delimited.

Where the following placeholders should be provided:
- `description`: a human-readable description of what is being deprecated
- `date`: the target date that this will be deprecated. This should be expressed following the format in [ISO 8601](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1), e.g. "2022-10-31".
- `url`: a fully qualified url that the user can follow to learn more about what is being deprecated, preferably to Azure Updates.

For example:
- `azure-deprecating: API version 2009-27-07 will retire on 2022-12-01 (https://azure.microsoft.com/updates/video-analyzer-retirement);TLS 1.0 & 1.1 will retire on 2020-10-30 (https://azure.microsoft.com/updates/azure-active-directory-registration-service-is-ending-support-for-tls-10-and-11/)`
- `azure-deprecating: Model version 2021-01-15 used in Sentiment analysis will retire on 2022-12-01 (https://aka.ms/ta-modelversions?sentimentAnalysis)`
- `azure-deprecating: TLS 1.0 & 1.1 support will retire on 2022-10-01 (https://devblogs.microsoft.com/devops/deprecating-weak-cryptographic-standards-tls-1-0-and-1-1-in-azure-devops-services/)`

<a href="#deprecation-header-review" name="deprecation-header-review">:no_entry:</a> **DO NOT** introduce this header without approval from [Azure Breaking Change Reviewers](mailto:azbreakchangereview@microsoft.com) and an official deprecation notice on [Azure Updates](https://azure.microsoft.com/updates/).

<a href="#repeatability" name="repeatability"></a>
### Repeatability of requests

Fault tolerant applications require that clients retry requests for which they never got a response, and services must handle these retried requests idempotently. In Azure, all HTTP operations are naturally idempotent except for POST used to create a resource and [POST when used to invoke an action](
https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#performing-an-action).

<a href="#repeatability-headers" name="repeatability-headers">:ballot_box_with_check:</a> **YOU SHOULD** support repeatable requests as defined in [OASIS Repeatable Requests Version 1.0](https://docs.oasis-open.org/odata/repeatable-requests/v1.0/repeatable-requests-v1.0.html) for POST operations to make them retriable.
- The tracked time window (difference between the `Repeatability-First-Sent` value and the current time) **MUST** be at least 5 minutes.
- Document the POST operation's support for the `Repeatability-First-Sent`, `Repeatability-Request-ID`, and `Repeatability-Result` headers in the API contract and documentation.
- Any operation that does not support repeatability headers should return a 501 (Not Implemented) response for any request that contains valid repeatability request headers.

### Long-Running Operations & Jobs

A _long-running operation (LRO)_ is typically an operation that should execute synchronously, but due to services not wanting to maintain long-lived connections (>1 seconds) and load-balancer timeouts, the operation must execute asynchronously. For this pattern, the client initiates the operation on the service, and then the client repeatedly polls the service (via another API call) to track the operation's progress/completion.

LROs are always started by 1 logical client and may be polled (have their status checked) by the same client, another client, or even multiple clients/browsers. An example would be a dashboard or portal that shows all the operations along with their status.  See the [Long Running Operations section](./ConsiderationsForServiceDesign.md#long-running-operations) in Considerations for Service Design for an introduction to the design of long-running operations.

<a href="#lro-response-time" name="lro-response-time">:white_check_mark:</a> **DO** implement an operation as an LRO if the 99th percentile response time is greater than 1 second and when the client should poll the operation before making more progress.

<a href="#lro-no-patch-lro" name="lro-no-patch-lro">:no_entry:</a> **DO NOT** implement PATCH as an LRO. If LRO update semantics are required, implement it using the [LRO POST action pattern](#lro-existing-resource) .

#### Patterns to Initiate a Long-Running Operation

<a href="#lro-valid-inputs-synchronously" name="lro-valid-inputs-synchronously">:white_check_mark:</a> **DO** perform as much validation as practical when initiating an LRO operation to alert clients of errors early.

<a href="#lro-returns-operation-location" name="lro-returns-operation-location">:white_check_mark:</a> **DO** include an `operation-location` response header with the absolute URL of the status monitor for the operation.

<a href="#lro-operation-location-includes-api-version" name="lro-operation-location-includes-api-version">:ballot_box_with_check:</a> **YOU SHOULD** include the `api-version` query parameter in the `operation-location` response header with the same version passed on the initial request but expect a client to change the `api-version` value to whatever a new/different client desires it to be.

<a href="#lro-put-response-headers" name="lro-put-response-headers">:white_check_mark:</a> **DO** include response headers with any additional values needed for a [GET polling request](#lro-poll) to the status monitor (e.g. location).

#### Create or replace operation with additional long-running processing
<a href="#put-operation-with-additional-long-running-processing" name="put-operation-with-additional-long-running-processing"></a>

<a href="#lro-create-init" name="lro-create-init">:white_check_mark:</a> **DO** use the following pattern when implementing an operation that creates or replaces a resource that involves additional long-running processing:

```text
PUT /UrlToResourceBeingCreated?api-version=<api-version>
operation-id: <optionalStatusMonitorResourceId>

<JSON Resource in body>
```

The response must look like this:

```text
201 Created
operation-id: <statusMonitorResourceId>
operation-location: https://operations/<operation-id>?api-version=<api-version>

<JSON Resource in body>
```

The request and response body schemas must be identical and represent the resource.

The PUT creates or replaces the resource immediately and returns but the additional long-running processing can take time to complete.

For an idempotent PUT (same `operation-id` or same request body within some short time window), the service should return the same response as shown above.

For a non-idempotent PUT, the service can choose to overwrite the existing resource (as if the resource were deleted) or the service can return `409-Conflict` with the error's code property indicated why this PUT operation failed.

<a href="#lro-put-operation-id-request-header" name="lro-put-operation-id-request-header">:white_check_mark:</a> **DO** allow the client to pass an `Operation-Id` header with a ID for the status monitor for the operation.

If the `Operation-Id` header is not specified, the service may create an operation-id (typically a GUID) and return it via the `operation-id` and `operation-location` response headers; in this case the service must figure out how to deal with retries/idempotency.

<a href="#lro-put-operation-id-default-is-guid" name="lro-put-operation-id-default-is-guid">:white_check_mark:</a> **DO** generate an ID (typically a GUID) for the status monitor if the `Operation-Id` header was not passed by the client.

<a href="#lro-put-operation-id-unique-except-retries" name="lro-put-operation-id-unique-except-retries">:white_check_mark:</a> **DO** fail a request with a `409-Conflict` if the `Operation-Id` header matches an existing operation unless the request is identical to the prior request (a retry scenario).

<a href="#lro-put-valid-inputs-synchronously" name="lro-put-valid-inputs-synchronously">:white_check_mark:</a> **DO** perform as much validation as practical when initiating the operation to alert clients of errors early.

<a href="#lro-put-returns-200-or-201" name="lro-put-returns-200-or-201">:white_check_mark:</a> **DO** return a `201-Created` status code for create or `200-OK` for replace from the initial request with a representation of the resource, if the resource was created or replaced successfully.

<a href="#lro-put-returns-operation-id-header" name="lro-put-returns-operation-id-header">:white_check_mark:</a> **DO** include an `Operation-Id` header in the response with the ID of the status monitor for the operation.

<a href="#lro-put-returns-operation-location" name="lro-put-returns-operation-location">:ballot_box_with_check:</a> **YOU SHOULD** include an `Operation-Location` header in the response with the absolute URL of the status monitor for the operation.

<a href="#lro-put-operation-location-includes-api-version" name="lro-put-operation-location-includes-api-version">:ballot_box_with_check:</a> **YOU SHOULD** include the `api-version` query parameter in the `Operation-Location` header with the same version passed on the initial request.

#### DELETE LRO pattern

<a href="#lro-delete" name="lro-delete">:white_check_mark:</a> **DO** use the following pattern when implementing an LRO operation to delete a resource:

```text
DELETE /UrlToResourceBeingDeleted?api-version=<api-version>
operation-id: <optionalStatusMonitorResourceId>
```

The response must look like this:

```text
202 Accepted
operation-id: <statusMonitorResourceId>
operation-location: https://operations/<operation-id>
```

Consistent with non-LRO DELETE operations, if a request body is specified, return `400-Bad Request`.

<a href="#lro-delete-operation-id-request-header" name="lro-delete-operation-id-request-header">:white_check_mark:</a> **DO** allow the client to pass an `Operation-Id` header with an ID for the operation's status monitor.

<a href="#lro-delete-operation-id-default-is-guid" name="lro-delete-operation-id-default-is-guid">:white_check_mark:</a> **DO** generate an ID (typically a GUID) for the status monitor if the `Operation-Id` header was not passed by the client.

<a href="#lro-delete-returns-202" name="lro-delete-returns-202">:white_check_mark:</a> **DO** return a `202-Accepted` status code from the request that initiates an LRO if the processing of the operation was successfully initiated.

<a href="#lro-delete-returns-only-202" name="lro-delete-returns-only-202">:warning:</a> **YOU SHOULD NOT** return any other `2xx` status code from the initial request of an LRO -- return `202-Accepted` and a status monitor even if processing was completed before the initiating request returns.

#### LRO action on a resource pattern
<a href="#post-or-delete-lro-pattern" name="post-or-delete-lro-pattern"></a><!-- Preserve old header link -->

<a href="#lro-existing-resource" name="lro-existing-resource">:white_check_mark:</a> **DO** use the following pattern when implementing an LRO action operating on an existing resource:

```text
POST /UrlToExistingResource:<action>?api-version=<api-version>&<actionParamsGoHere>
operation-id: <optionalStatusMonitorResourceId>`

<JSON Action parameters can go in body if query params don't work>
```

The response must look like this:

```text
202 Accepted
operation-id: <statusMonitorResourceId>
operation-location: https://operations/<operation-id>

<JSON Status Monitor Resource in body>
```

The request body contains information to be used to execute the action.

For an idempotent POST (same `operation-id` and request body within some short time window), the service should return the same response as the initial request.

For a non-idempotent POST, the service can treat the POST operation as idempotent (if performed within a short time window) or can treat the POST operation as initiating a brand new LRO action operation.

<a href="#lro-no-post-create" name="lro-no-post-create">:no_entry:</a> **DO NOT** use a long-running POST to create a resource -- use PUT as described above.

<a href="#lro-operation-id-request-header" name="lro-operation-id-request-header">:white_check_mark:</a> **DO** allow the client to pass an `Operation-Id` header with an ID for the operation's status monitor.

<a href="#lro-operation-id-default-is-guid" name="lro-operation-id-default-is-guid">:white_check_mark:</a> **DO** generate an ID (typically a GUID) for the status monitor if the `Operation-Id` header was not passed by the client.

<a href="#lro-operation-id-unique-except-retries" name="lro-operation-id-unique-except-retries">:white_check_mark:</a> **DO** fail a request with a `409-Conflict` if the `Operation-Id` header matches an existing operation unless the request is identical to the prior request (a retry scenario).

<a href="#lro-returns-202" name="lro-returns-202">:white_check_mark:</a> **DO** return a `202-Accepted` status code from the request that initiates an LRO action on a resource if the processing of the operation was successfully initiated.

<a href="#lro-returns-only-202" name="lro-returns-only-202">:warning:</a> **YOU SHOULD NOT** return any other `2xx` status code from the initial request of an LRO -- return `202-Accepted` and a status monitor even if processing was completed before the initiating request returns.

<a href="#lro-returns-status-monitor" name="lro-returns-status-monitor">:white_check_mark:</a> **DO** return a status monitor in the response body as described in [Obtaining status and results of long-running operations](#obtaining-status-and-results-of-long-running-operations).

#### LRO action with no related resource pattern

<a href="#lro-action-no-resource" name="lro-action-no-resource">:white_check_mark:</a> **DO** use the following pattern when implementing an LRO action not related to a specific resource (such as a batch operation):

```text
PUT <operation-endpoint>/<operation-id>?api-version=<api-version>

<JSON body with parameters for the operation>>
```

The response must look like this:

```text
201 Created
operation-location: <absolute URL of status monitor>

<JSON Status Monitor Resource in body>
```

<a href="#lro-put-action-operation-endpoint" name="lro-put-action-operation-endpoint">:ballot_box_with_check:</a> **YOU SHOULD**
define a unique operation endpoint for each LRO action with no related resource.

<a href="#lro-put-action-operation-id" name="lro-put-action-operation-id-in-path">:white_check_mark:</a> **DO** require the
`Operation-Id` as the final path segment in the URL.

Note: The `operation-id` URL segment (not header) is *required*, forcing the client to specify the status monitor's resource ID
and is also used for retries/idempotency.

<a href="#lro-put-action-returns-201" name="lro-put-action-returns-201">:white_check_mark:</a> **DO** return a `201 Created` status code
with an `operation-location` response header if the LRO Action operation was accepted for processing.

<a href="#lro-put-action-returns-status-monitor" name="lro-put-action-returns-status-monitor">:white_check_mark:</a> **DO** return a
status monitor in the response body that contains the operation status, request parameters, and when the operation completes either
the operation result or error.

Note: Since all request parameters must be present in the status monitor,
the request and response body of the PUT can be defined with a single schema.

<a href="#lro-put-action-status-monitor-url" name="lro-put-action-status-monitor-url">:ballot_box_with_check:</a> **YOU SHOULD**
return the status monitor for an operation for a subsequent GET on the URL that initiates the LRO, and use this endpoint as
the status monitor URL returned in the `operation-location` response header.

#### The Status Monitor Resource

All patterns that initiate a LRO either implicitly or explicitly create a [Status Monitor resource](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.3) in the service's `operations` collection.

<a href="#lro-status-monitor-structure" name="lro-status-monitor-structure">:white_check_mark:</a> **DO** return a status monitor in the response body that conforms with the following structure:

Property | Type        | Required | Description
-------- | ----------- | :------: | -----------
`id`     | string      | true     | The unique id of the operation
`kind`   | string enum | true(*)  | The kind of operation
`status` | string enum | true     | The operation's current status: "NotStarted", "Running", "Succeeded", "Failed", and "Canceled"
`error`  | ErrorDetail |          | If `status`=="Failed", contains reason for failure
`result` | object      |          | If `status`=="Succeeded" && Action LRO (POST or PUT), contains success result if needed
additional<br/>properties | | | Additional named or dynamic properties of the operation

(*): When a status monitor endpoint supports multiple operations with different result structures or additional properties,
the status monitor **must** be polymorphic -- it **must** contain a required `kind` property that indicates the kind of long-running operation.

#### Obtaining status and results of long-running operations

<a href="#lro-poll" name="lro-poll">:white_check_mark:</a> **DO** use the following pattern to allow clients to poll the current state of a Status Monitor resource:

```text
GET <operation-endpoint>/<operation-id>?api-version=<api-version>
```

The response must look like this:

```text
200 OK
retry-after: <delay-seconds>    (if status not terminal)

<JSON Status Monitor Resource in body>
```

<a href="#lro-status-monitor-get-returns-200" name="lro-status-monitor-get-returns-200">:white_check_mark:</a> **DO** support the GET method on the status monitor endpoint that returns a `200-OK` response with the current state of the status monitor.

<a href="#lro-status-monitor-accepts-any-api-version" name="lro-status-monitor-accepts-any-api-version">:ballot_box_with_check:</a> **YOU SHOULD** allow any valid value of the `api-version` query parameter to be used in the GET operation on the status monitor.

- Note: Clients may replace the value of `api-version` in the `operation-location` URL with a value appropriate for their application. Remember that the client initiating the LRO may not be the same client polling the LRO's status.

<a href="#lro-status-monitor-includes-all-fields" name="lro-status-monitor-includes-all-fields">:white_check_mark:</a> **DO** include the `id` of the operation and any other values needed for the client to form a GET request to the status monitor (e.g. a `location` path parameter).

<a href="#lro-status-monitor-post-action-result" name="lro-status-monitor-post-action-result">:white_check_mark:</a> **DO** include the `result` property (if any) in the status monitor for a POST action-type long-running operation when the operation completes successfully.

<a href="#lro-status-monitor-no-resource-result" name="lro-status-monitor-no-resource-result">:no_entry:</a> **DO NOT** include a `result` property in the status monitor for a long-running operation that is not an action-type long-running operation.

<a href="#lro-status-monitor-retry-after" name="lro-status-monitor-retry-after">:white_check_mark:</a> **DO** include a `retry-after` header in the response if the operation is not complete. The value of this header should be an integer number of seconds that the client should wait before polling the status monitor again.

<a href="#lro-status-monitor-retention" name="lro-status-monitor-retention">:white_check_mark:</a> **DO** retain the status monitor resource for some publicly documented period of time (at least 24 hours) after the operation completes.

#### Pattern to List Status Monitors

Use the following patterns to allow clients to list Status Monitor resources.

<a href="#lro-list-status-monitors" name="lro-list-status-monitors">:ballot_box_with_check:</a>
**YOU MAY** support a GET method on any status monitor collection URL that returns a list of the status monitors in that collection.

<a href="#lro-put-action-list-status-monitors" name="lro-put-action-list-status-monitors">:ballot_box_with_check:</a>
**YOU SHOULD** support a list operation for any status monitor collection that includes status monitors for LRO Actions with no related resource.

<a href="#lro-list-status-monitors-filter" name="lro-list-status-monitors-filter">:ballot_box_with_check:</a>
**YOU SHOULD** support the `filter` query parameter on the list operation for any polymorphic status monitor collection and support filtering on the `kind` value of the status monitor.

For example, the following request should return all status monitor resources whose `kind` is either "VMInitializing" *or* "VMRebooting"
and whose status is "NotStarted" *or* "Succeeded".

```text
GET /operations?filter=(kind eq 'VMInitializing' or kind eq 'VMRebooting') and (status eq 'NotStarted' or status eq 'Succeeded')
```

<a href="#byos" name="byos"></a>
### Bring your own Storage (BYOS)

Many services need to store and retrieve data files. For this scenario, the service should not implement its own
storage APIs and should instead leverage the existing Azure Storage service. When doing this, the customer
"owns" the storage account and just tells your service to use it. Colloquially, we call this <i>Bring Your Own Storage</i> as the customer is bringing their storage account to another service. BYOS provides significant benefits to service implementors: security, performance, uptime, etc. And, of course, most Azure customers are already familiar with the Azure Storage service.

While Azure Managed Storage may be easier to get started with, as your service evolves and matures, BYOS provides the most flexibility and implementation choices. Further, when designing your APIs, be cognizant of expressing storage concepts and how clients will access your data. For example, if you are working with blobs, then you should not expose the concept of folders.

<a href="#byos-pattern" name="byos-pattern">:white_check_mark:</a> **DO** use the Bring Your Own Storage pattern.

<a href="#byos-prefix-for-folder" name="byos-prefix-for-folder">:white_check_mark:</a> **DO** use a blob prefix for a logical folder (avoid terms such as `directory`, `folder`, or `path`).

<a href="#byos-allow-container-reuse" name="byos-allow-container-reuse">:no_entry:</a> **DO NOT** require a fresh container per operation.

<a href="#byos-authorization" name="byos-authorization">:white_check_mark:</a> **DO** use managed identity and Role Based Access Control ([RBAC](https://docs.microsoft.com/azure/role-based-access-control/overview)) as the mechanism allowing customers to grant permission to their Storage account to your service.

<a href="#byos-define-rbac-roles" name="byos-define-rbac-roles">:white_check_mark:</a> **DO** Add RBAC roles for every service operation that requires accessing Storage scoped to the exact permissions.

<a href="#byos-rbac-compatibility" name="byos-rbac-compatibility">:white_check_mark:</a> **DO** Ensure that RBAC roles are backward compatible, and specifically, do not take away permissions from a role that would break the operation of the service. Any change of RBAC roles that results in a change of the service behavior is considered a breaking change.


#### Handling 'downstream' errors
It is not uncommon to rely on other services, e.g. storage, when implementing your service. Inevitably, the services you depend on will fail. In these situations, you can include the downstream error code and text in the inner-error of the response body. This provides a consistent pattern for handling errors in the services you depend upon.

<a href="#byos-include-downstream-errors" name="byos-include-downstream-errors">:white_check_mark:</a> **DO** include error from downstream services as the 'inner-error' section of the response body.

#### Working with files
Generally speaking, there are two patterns that you will encounter when working with files; single file access, and file collections.

##### Single file access
Designing an API for accessing a single file, depending on your scenario, is relatively straight forward.

<a href="#byos-sas-token" name="byos-sas-token">:heavy_check_mark:</a> **YOU MAY** use a Shared Access Signature [SAS](https://docs.microsoft.com/azure/storage/common/storage-sas-overview) to provide access to a single file. SAS is considered the minimum security for files and can be used in lieu of, or in addition to, RBAC.

<a href="#byos-http-insecure" name="byos-http-insecure">:ballot_box_with_check:</a> **YOU SHOULD** if using HTTP (not HTTPS) document to users that all information is sent over the wire in clear text.

<a href="#byos-http-status-code" name="byos-http-status-code">:white_check_mark:</a> **DO** return an HTTP status code representing the result of your service operation's behavior.

<a href="#byos-include-storage-error" name="byos-include-storage-error">:white_check_mark:</a> **DO** include the Storage error information in the 'inner-error' section of an error response if the error was the result of an internal Storage operation failure. This helps the client determine the underlying cause of the error, e.g.: a missing storage object or insufficient permissions.

<a href="#byos-support-single-object" name="byos-support-single-object">:white_check_mark:</a> **DO** allow the customer to specify a URL path to a single Storage object if your service requires access to a single file.

<a href="#byos-last-modified" name="byos-last-modified">:heavy_check_mark:</a> **YOU MAY** allow the customer to provide a [last-modified](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2) timestamp (in RFC 7231 format) for read-only files. This allows the client to specify exactly which version of the files your service should use.
When reading a file, your service passes this timestamp to Azure Storage using the [if-unmodified-since](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4) request header. If the Storage operation fails with 412, the Storage object was modified and your service operation should return an appropriate 4xx status code and return the Storage error in your operation's 'inner-error' (see guideline above).

<a href="#byos-folder-support" name="byos-folder-support">:white_check_mark:</a> **DO** allow the customer to specify a URL path to a logical folder (via prefix and delimiter) if your service requires access to multiple files (within this folder). For more information, see [List Blobs API](https://docs.microsoft.com/rest/api/storageservices/list-blobs)

<a href="#byos-extensions" name="byos-extensions">:heavy_check_mark:</a> **YOU MAY** offer an `extensions` field representing an array of strings indicating file extensions of desired blobs within the logical folder.

A common pattern when working with multiple files is for your service to receive requests that contain the location(s) of files to process ("input") and a location(s) to place any files that result from processing ("output"). Note: the terms "input" and "output" are just examples; use terms more appropriate to your service's domain.

For example, a service's request body to configure BYOS may look like this:

```json
{
  "input":{
    "location": "https://mycompany.blob.core.windows.net/documents/english/?<sas token>",
    "delimiter": "/",
    "extensions" : [ ".bmp", ".jpg", ".tif", ".png" ],
    "lastModified": "Wed, 21 Oct 2015 07:28:00 GMT"
  },
  "output":{
    "location": "https://mycompany.blob.core.windows.net/documents/spanish/?<sas token>",
    "delimiter":"/"
  }
}
```

Depending on the requirements of the service, there can be any number of "input" and "output" sections, including none.

<a href="#byos-location-and-delimiter" name="byos-location-and-delimiter">:white_check_mark:</a> **DO** include a JSON object that has string values for "location" and "delimiter". For "location", the customer must pass a URL to a blob prefix which represents a directory. For "delimiter", the customer must specify the delimiter character they desire to use in the location URL; typically "/" or "\".

<a href="#byos-directory-last-modified" name="byos-directory-last-modified">:heavy_check_mark:</a> **YOU MAY** support the "lastModified" field for input directories (see guideline above).

<a href="#byos-sas-for-input-location" name="byos-sas-for-input-location">:white_check_mark:</a> **DO** support a "location" URL with a container-scoped SAS that has a minimum of `listing` and `read` permissions for input directories.

<a href="#byos-sas-for-output-location" name="byos-sas-for-output-location">:white_check_mark:</a> **DO** support a "location" URL with a container-scoped SAS that has a minimum of `write` permissions for output directories.

<a href="#condreq" name="condreq"></a>
### Conditional Requests

The [HTTP Standard][] defines request headers that clients may use to specify a _precondition_
for execution of an operation. These headers allow clients to implement efficient caching mechanisms
and avoid data loss in the event of concurrent updates to a resource. The headers that specify conditional execution are `If-Match`, `If-None-Match`, `If-Modified-Since`, `If-Unmodified-Since`, and `If-Range`.

[HTTP Standard]: https://datatracker.ietf.org/doc/html/rfc9110

<!-- condreq-support-etags-consistently has been subsumed by condreq-support but we retain the anchor to avoid broken links -->
<a href="#condreq-support-etags-consistently" name="condreq-support-etags-consistently"></a>
<!-- condreq-for-read has been subsumed by condreq-support but we retain the anchor to avoid broken links -->
<a href="#condreq-for-read" name="condreq-for-read"></a>
<!-- condreq-no-pessimistic-update has been subsumed by condreq-support but we retain the anchor to avoid broken links -->
<a href="#condreq-no-pessimistic-update" name="condreq-no-pessimistic-update"></a>
<a href="#condreq-support" name="condreq-support">:white_check_mark:</a> **DO** honor any precondition headers received as part of a client request.

The HTTP Standard does not allow precondition headers to be ignored, as it can be unsafe to do so.

<a href="#condreq-unsupported-error" name="condreq-unsupported-error">:white_check_mark:</a> **DO** return the appropriate precondition failed error response if the service cannot verify the truth of the precondition.

Note: The Azure Breaking Changes review board will allow a GA service that currently ignores precondition headers to begin honoring them in a new API version without a formal breaking change notification. The potential for disruption to customer applications is low and outweighed by the value of conforming to HTTP standards.

While conditional requests can be implemented using last modified dates, entity tags ("ETags") are strongly
preferred since last modified dates cannot distinguish updates made less than a second apart.

<a href="#condreq-return-etags" name="condreq-return-etags">:ballot_box_with_check:</a> **YOU SHOULD** return an `ETag` with any operation returning the resource or part of a resource or any update of the resource (whether the resource is returned or not).

#### Conditional Request behavior

This section gives a summary of the processing to perform for precondition headers.
See the [Conditional Requests section of the HTTP Standard][] for details on how and when to evaluate these headers.

[Conditional Requests section of the HTTP Standard]: https://datatracker.ietf.org/doc/html/rfc9110#name-conditional-requests

<a href="#condreq-for-read-behavior" name="condreq-for-read-behavior">:white_check_mark:</a> **DO** adhere to the following table for processing a GET request with precondition headers:

| GET Request | Return code | Response                                    |
|:------------|:------------|:--------------------------------------------|
| ETag value = `If-None-Match` value   | `304-Not Modified` | no additional information   |
| ETag value != `If-None-Match` value  | `200-OK`           | Response body include the serialized value of the resource (typically JSON)    |

For more control over caching, please refer to the `cache-control` [HTTP header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control).

<a href="#condreq-behavior" name="condreq-behavior">:white_check_mark:</a> **DO** adhere to the following table for processing a PUT, PATCH, or DELETE request with precondition headers:

| Operation   | Header        | Value | ETag check | Return code | Response       |
|:------------|:--------------|:------|:-----------|:------------|----------------|
| PATCH / PUT | `If-None-Match` | *     | check for _any_ version of the resource ('*' is a wildcard used to match anything), if none are found, create the resource. | `200-OK` or </br> `201-Created` </br> | Response header MUST include the new `ETag` value. Response body SHOULD include the serialized value of the resource (typically JSON).  |
| PATCH / PUT | `If-None-Match` | *     | check for _any_ version of the resource, if one is found, fail the operation |  `412-Precondition Failed` | Response body SHOULD return the serialized value of the resource (typically JSON) that was passed along with the request.|
| PATCH / PUT | `If-Match` | value of ETag     | value of `If-Match` equals the latest ETag value on the server, confirming that the version of the resource is the most current | `200-OK` or </br> `201-Created` </br> | Response header MUST include the new `ETag` value. Response body SHOULD include the serialized value of the resource (typically JSON).  |
| PATCH / PUT | `If-Match` | value of ETag     | value of `If-Match` header DOES NOT equal the latest ETag value on the server, indicating a change has ocurred since after the client fetched the resource|  `412-Precondition Failed` | Response body SHOULD return the serialized value of the resource (typically JSON) that was passed along with the request.|
| DELETE      | `If-Match` | value of ETag     | value matches the latest value on the server | `204-No Content` | Response body SHOULD be empty.  |
| DELETE      | `If-Match` | value of ETag     | value does NOT match the latest value on the server | `412-Preconditioned Failed` | Response body SHOULD be empty.|

#### Computing ETags

The strategy that you use to compute the `ETag` depends on its semantic. For example, it is natural, for resources that are inherently versioned, to use the version as the value of the `ETag`. Another common strategy for determining the value of an `ETag` is to use a hash of the resource. If a resource is not versioned, and unless computing a hash is prohibitively expensive, this is the preferred mechanism.

<a href="#condreq-etag-is-hash" name="condreq-etag-is-hash">:ballot_box_with_check:</a> **YOU SHOULD** use a hash of the representation of a resource rather than a last modified/version number

While it may be tempting to use a revision/version number for the resource as the ETag, it interferes with client's ability to retry update requests. If a client sends a conditional update request, the service acts on the request, but the client never receives a response, a subsequent identical update will be seen as a conflict even though the retried request is attempting to make the same update.

<a href="#condreq-etag-hash-entire-resource" name="condreq-etag-hash-entire-resource">:ballot_box_with_check:</a> **YOU SHOULD**, if using a hash strategy, hash the entire resource.

<a href="#condreq-strong-etag-for-range-requests" name="condreq-strong-etag-for-range-requests">:ballot_box_with_check:</a> **YOU SHOULD**, if supporting range requests, use a strong ETag in order to support caching.

<a href="#condreq-timestamp-precision" name="condreq-timestamp-precision">:heavy_check_mark:</a> **YOU MAY** use or, include, a timestamp in your resource schema. If you do this, the timestamp shouldn't be returned with more than subsecond precision, and it SHOULD be consistent with the data and format returned, e.g. consistent on milliseconds.

<a href="#condreq-weak-etags-allowed" name="condreq-weak-etags-allowed">:heavy_check_mark:</a> **YOU MAY** consider Weak ETags if you have a valid scenario for distinguishing between meaningful and cosmetic changes or if it is too expensive to compute a hash.

<a href="#condreq-etag-depends-on-encoding" name="condreq-etag-depends-on-encoding">:white_check_mark:</a> **DO**, when supporting multiple representations (e.g. Content-Encodings) for the same resource, generate different ETag values for the different representations.

<a href="#substrings" name="substrings"></a>
### Returning String Offsets & Lengths (Substrings)

All string values in JSON are inherently Unicode and UTF-8 encoded, but clients written in a high-level programming language must work with strings in that language's string encoding, which may be UTF-8, UTF-16, or CodePoints (UTF-32).
When a service response includes a string offset or length value, it should specify these values in all 3 encodings to simplify client development and ensure customer success when isolating a substring.
See the [Returning String Offsets & Lengths] section in Considerations for Service Design for more detail, including an example JSON response containing string offset and length fields.

[Returning String Offsets & Lengths]: https://github.com/microsoft/api-guidelines/blob/vNext/azure/ConsiderationsForServiceDesign.md#returning-string-offsets--lengths-substrings

<a href="#substrings-return-value-for-each-encoding" name="substrings-return-value-for-each-encoding">:white_check_mark:</a> **DO** include all 3 encodings (UTF-8, UTF-16, and CodePoint) for every string offset or length value in a service response.

<a href="#substrings-return-value-structure" name="substrings-return-value-structure">:white_check_mark:</a> **DO** define every string offset or length value in a service response as an object with the following structure:

| Property    | Type    | Required | Description |
| ----------- | ------- | :------: | ----------- |
| `utf8`      | integer | true     | The offset or length of the substring in UTF-8 encoding |
| `utf16`     | integer | true     | The offset or length of the substring in UTF-16 encoding |
| `codePoint` | integer | true     | The offset or length of the substring in CodePoint encoding |

<a href="#telemetry" name="telemetry"></a>
### Distributed Tracing & Telemetry

Azure SDK client guidelines specify that client libraries must send telemetry data through the `User-Agent` header, `X-MS-UserAgent` header, and Open Telemetry.
Client libraries are required to send telemetry and distributed tracing information on every  request. Telemetry information is vital to the effective operation of your service and should be a consideration from the outset of design and implementation efforts.

<a href="#telemetry-headers" name="telemetry-headers">:white_check_mark:</a> **DO** follow the Azure SDK client guidelines for supporting telemetry headers and Open Telemetry.

<a href="#telemetry-allow-unrecognized-headers" name="telemetry-allow-unrecognized-headers">:no_entry:</a> **DO NOT** reject a call if you have custom headers you don't understand, and specifically, distributed tracing headers.

**Additional References**
- [Azure SDK client guidelines](https://azure.github.io/azure-sdk/general_azurecore.html)
- [Azure SDK User-Agent header policy](https://azure.github.io/azure-sdk/general_azurecore.html#azurecore-http-telemetry-x-ms-useragent)
- [Azure SDK Distributed tracing policy](https://azure.github.io/azure-sdk/general_azurecore.html#distributed-tracing-policy)
- [Open Telemetry](https://opentelemetry.io/)

In addition to distributed tracing, Azure also uses a set of common correlation headers:

|Name                         |Applies to|Description|
|-----------------------------|----------|-----------|
|x-ms-client-request-id       |Both      |Optional. Caller-specified value identifying the request, in the form of a GUID with no decoration such as curly braces (e.g. `x-ms-client-request-id: 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0`). If the caller provides this header the service **must** include this in their log entries to facilitate correlation of log entries for a single request. Because this header can be client-generated, it should not be assumed to be unique by the service implementation.
|x-ms-request-id              |Response  |Required. Service generated correlation id identifying the request, in the form of a GUID with no decoration such as curly braces. In contrast to the the `x-ms-client-request-id`, the service **must** ensure that this value is globally unique. Services should log this value with their traces to facilitate correlation of log entries for a single request.

## Final thoughts
These guidelines describe the upfront design considerations, technology building blocks, and common patterns that Azure teams encounter when building an API for their service. There is a great deal of information in them that can be difficult to follow. Fortunately, at Microsoft, there is a team committed to ensuring your success.

The Azure REST API Stewardship board is a collection of dedicated architects that are passionate about helping Azure service teams build interfaces that are intuitive, maintainable, consistent, and most importantly, delight our customers.
Because APIs affect nearly all downstream decisions, you are encouraged to reach out to the Stewardship board early in the development process.
These architects will work with you to apply these guidelines and identify any hidden pitfalls in your design. For more information on how to part with the Stewardship board, please refer to [Considerations for Service Design](./ConsiderationsForServiceDesign.md).


================================================
FILE: azure/README.md
================================================
# Azure REST API Guidance
When building software components that will be used by developers to build other software, providing APIs that are easy to use, fit to purpose, scalable, maintainable, and consistent across your product can make the difference between success and failure for your software. 

Designing powerful APIs with strong defaults, consistent behavior across related projects, and ease of use for developers arises from putting yourself in the shoes of the person using your interfaces, and taking their concerns to heart. The APIs you ship can have a dramatic long term effect on the health of your software product, and that is why the **REST API Stewardship Board** is here to help! We have published a collection of best practices, REST guidance, and OpenAPI style guidelines to help you create an amazing developer experience.
* [Considerations for Service Design](ConsiderationsForServiceDesign.md)
* [REST API Guidelines](Guidelines.md)
* [OpenAPI Style Guidelines](https://github.com/Azure/azure-api-style-guide/blob/main/README.md)
* [Versioning policy for Azure services, SDKs, and CLI tools](https://learn.microsoft.com/en-us/azure/developer/intro/azure-service-sdk-tool-versioning)
* [Breaking Changes](https://aka.ms/azapi/breakingchanges) <sub>Note: Internal Microsoft link</sub>

You can reach out to us via [email](mailto://azureapirbcore@microsoft.com) or in our [Teams](https://teams.microsoft.com/l/team/19%3a3ebb18fded0e47938f998e196a52952f%40thread.tacv2/conversations?groupId=1a10b50c-e870-4fe0-8483-bf5542a8d2d8&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) channel.

<sub>Note: The Teams channel is internal MS.</sup>


================================================
FILE: azure/VersioningGuidelines.md
================================================
# Azure Versioning Guidelines

## History

<details>
  <summary>Expand change history</summary>

| Date        | Notes                                                          |
| ----------- | -------------------------------------------------------------- |
| 2024-Nov-14 | Azure Service Versioning & Breaking Change Guidelines       |

</details>

## Guidelines

This document provides a "Dos and Don'ts" list for complying with the Azure Versioning and Breaking Change Policy,
as documented [internally](aka.ms/AzBreakingChangesPolicy) and [externally](https://learn.microsoft.com/azure/developer/intro/azure-service-sdk-tool-versioning).

:white_check_mark: **DO** thoroughly ensure/test the API contract is entirely correct before merging it into a production branch of the specs repo.

Testing helps avoid "BugFix" changes to the API definition. Testing should be done at the HTTP level as well as through generated SDKs.

:white_check_mark: **DO** retire all prior preview API versions 90 days after a new GA or preview API version is released.

:white_check_mark: **DO** contact the Azure Breaking Change Review board to coordinate communications to customers
when releasing an API version requiring the retirement of a prior version.

:white_check_mark: **DO** create a new preview API version for any features that should remain in preview following a new GA release.

:white_check_mark: **DO** use a date strictly later than the most recent GA API version when releasing
a new preview API version.

:white_check_mark: **DO** deprovision any API version that has been retired. Retired APIs versions should behave like
an unknown API version (see [ref](https://aka.ms/azapi/guidelines#versioning-api-version-unsupported)).

:white_check_mark: **DO** remove retired API versions from the azure-rest-api-specs repo.

:white_check_mark: **DO** review any change to service behavior that could disrupt customers with the Azure Breaking Changes review board, even if the change is not part of the API definition.

Some examples of behavior changes that must be reviewed are:
- Introducing or changing rate limits to be more restrictive than previously
- Changing the permissions required to successfully execute an operation

:no_entry: **DO NOT** change the behavior of an API version that is available to customers either in public preview or GA.
Changes in behavior should always be introduced in a new API version, with prior versions working as before.

:no_entry: **DO NOT** introduce breaking changes from a prior GA version just to satisfy ARM or Azure API guidelines.

Avoiding breaking changes in a GA API takes precedence over adherence to API guidelines and resolving linter errors.

:no_entry: **DO NOT** keep a preview feature in preview for more than 1 year; it must go GA (or be removed) within 1 year after introduction.


================================================
FILE: graph/Guidelines-deprecated.md
================================================

> # DEPRECATION NOTICE TO READERS
>
> This document is being deprecated and merged with the  [Microsoft Graph REST API Guidelines](GuidelinesGraph.md), with a removal date of July 1, 2024. Please refer to the notes below for the latest guidance.
>
> ## **Guidance for Microsoft Graph service teams**
>
> Graph service teams should reference the companion document, [Microsoft Graph REST API Guidelines](GuidelinesGraph.md) when building or modifying their services. This document and the associated pattern catalog provides a refined set of guidance targeted specifically for Microsoft Graph services.
>
---
# Microsoft REST API Guidelines

This are Microsoft's internal company-wide REST API design guidelines.
Teams at Microsoft typically reference this document when setting API design policy.
They may additionally create documents specific to their team, adding further guidance or making adjustments as appropriate to their circumstances.

## Microsoft REST API Guidelines Working Group

Name | Name | Name |
---------------------------- | -------------------------------------- | ----------------------------------------
Dave Campbell (CTO C+E)      | Rick Rashid (CTO ASG)                  | John Shewchuk (Technical Fellow, TED HQ)
Mark Russinovich (CTO Azure) | Steve Lucco (Technical Fellow, DevDiv) | Murali Krishnaprasad (Azure App Plat)
Rob Howard (ASG)             | Peter Torr  (OSG)                      | Chris Mullins (ASG)

<div style="font-size:150%">
Document editors: John Gossman (C+E), Chris Mullins (ASG), Gareth Jones (ASG), Rob Dolin (C+E), Mark Stafford (C+E)<br/>
</div>

# Microsoft REST API Guidelines

## 1. Abstract
The Microsoft REST API Guidelines, as a design principle, encourages application developers to have resources accessible to them via a RESTful HTTP interface.
To provide the smoothest possible experience for developers on platforms following the Microsoft REST API Guidelines, REST APIs SHOULD follow consistent design guidelines to make using them easy and intuitive.

This document establishes the guidelines Microsoft REST APIs SHOULD follow so RESTful interfaces are developed consistently.

## 2. Table of contents
<!-- TOC depthFrom:2 depthTo:4 orderedList:false updateOnSave:false withLinks:true -->

- [Microsoft REST API Guidelines](#microsoft-rest-api-guidelines)
  - [Microsoft REST API Guidelines Working Group](#microsoft-rest-api-guidelines-working-group)
- [Microsoft REST API Guidelines](#microsoft-rest-api-guidelines-1)
  - [1. Abstract](#1-abstract)
  - [2. Table of contents](#2-table-of-contents)
  - [3. Introduction](#3-introduction)
    - [3.1. Recommended reading](#31-recommended-reading)
  - [4. Interpreting the guidelines](#4-interpreting-the-guidelines)
    - [4.1. Application of the guidelines](#41-application-of-the-guidelines)
    - [4.2. Guidelines for existing services and versioning of services](#42-guidelines-for-existing-services-and-versioning-of-services)
    - [4.3. Requirements language](#43-requirements-language)
    - [4.4. License](#44-license)
  - [5. Taxonomy](#5-taxonomy)
    - [5.1. Errors](#51-errors)
    - [5.2. Faults](#52-faults)
    - [5.3. Latency](#53-latency)
    - [5.4. Time to complete](#54-time-to-complete)
    - [5.5. Long running API faults](#55-long-running-api-faults)
  - [6. Client guidance](#6-client-guidance)
    - [6.1. Ignore rule](#61-ignore-rule)
    - [6.2. Variable order rule](#62-variable-order-rule)
    - [6.3. Silent fail rule](#63-silent-fail-rule)
  - [7. Consistency fundamentals](#7-consistency-fundamentals)
    - [7.1. URL structure](#71-url-structure)
    - [7.2. URL length](#72-url-length)
    - [7.3. Canonical identifier](#73-canonical-identifier)
    - [7.4. Supported methods](#74-supported-methods)
      - [7.4.1. POST](#741-post)
      - [7.4.2. PATCH](#742-patch)
      - [7.4.3. Creating resources via PATCH (UPSERT semantics)](#743-creating-resources-via-patch-upsert-semantics)
      - [7.4.4. Options and link headers](#744-options-and-link-headers)
    - [7.5. Standard request headers](#75-standard-request-headers)
    - [7.6. Standard response headers](#76-standard-response-headers)
    - [7.7. Custom headers](#77-custom-headers)
    - [7.8. Specifying headers as query parameters](#78-specifying-headers-as-query-parameters)
    - [7.9. PII parameters](#79-pii-parameters)
    - [7.10. Response formats](#710-response-formats)
      - [7.10.1. Clients-specified response format](#7101-clients-specified-response-format)
      - [7.10.2. Error condition responses](#7102-error-condition-responses)
        - [ErrorResponse : Object](#errorresponse--object)
        - [Error : Object](#error--object)
        - [InnerError : Object](#innererror--object)
        - [Examples](#examples)
    - [7.11. HTTP Status Codes](#711-http-status-codes)
    - [7.12. Client library optional](#712-client-library-optional)
  - [8. CORS](#8-cors)
    - [8.1. Client guidance](#81-client-guidance)
      - [8.1.1. Avoiding preflight](#811-avoiding-preflight)
    - [8.2. Service guidance](#82-service-guidance)
  - [9. Collections](#9-collections)
    - [9.1. Item keys](#91-item-keys)
    - [9.2. Serialization](#92-serialization)
    - [9.3. Collection URL patterns](#93-collection-url-patterns)
      - [9.3.1. Nested collections and properties](#931-nested-collections-and-properties)
    - [9.4. Big collections](#94-big-collections)
    - [9.5. Changing collections](#95-changing-collections)
    - [9.6. Sorting collections](#96-sorting-collections)
      - [9.6.1. Interpreting a sorting expression](#961-interpreting-a-sorting-expression)
    - [9.7. Filtering](#97-filtering)
      - [9.7.1. Filter operations](#971-filter-operations)
      - [9.7.2. Operator examples](#972-operator-examples)
      - [9.7.3. Operator precedence](#973-operator-precedence)
    - [9.8. Pagination](#98-pagination)
      - [9.8.1. Server-driven paging](#981-server-driven-paging)
      - [9.8.2. Client-driven paging](#982-client-driven-paging)
      - [9.8.3. Additional considerations](#983-additional-considerations)
    - [9.9. Compound collection operations](#99-compound-collection-operations)
    - [9.10. Empty Results](#910-empty-results)
  - [10. Delta queries](#10-delta-queries)
    - [10.1. Delta links](#101-delta-links)
    - [10.2. Entity representation](#102-entity-representation)
    - [10.3. Obtaining a delta link](#103-obtaining-a-delta-link)
    - [10.4. Contents of a delta link response](#104-contents-of-a-delta-link-response)
    - [10.5. Using a delta link](#105-using-a-delta-link)
  - [11. JSON standardizations](#11-json-standardizations)
    - [11.1. JSON formatting standardization for primitive types](#111-json-formatting-standardization-for-primitive-types)
    - [11.2. Guidelines for dates and times](#112-guidelines-for-dates-and-times)
      - [11.2.1. Producing dates](#1121-producing-dates)
      - [11.2.2. Consuming dates](#1122-consuming-dates)
      - [11.2.3. Compatibility](#1123-compatibility)
    - [11.3. JSON serialization of dates and times](#113-json-serialization-of-dates-and-times)
      - [11.3.1. The `DateLiteral` format](#1131-the-dateliteral-format)
      - [11.3.2. Commentary on date formatting](#1132-commentary-on-date-formatting)
    - [11.4. Durations](#114-durations)
    - [11.5. Intervals](#115-intervals)
    - [11.6. Repeating intervals](#116-repeating-intervals)
  - [12. Versioning](#12-versioning)
    - [12.1. Versioning formats](#121-versioning-formats)
      - [12.1.1. Group versioning](#1211-group-versioning)
        - [Examples of group versioning](#examples-of-group-versioning)
    - [12.2. When to version](#122-when-to-version)
    - [12.3. Definition of a breaking change](#123-definition-of-a-breaking-change)
  - [13. Long running operations](#13-long-running-operations)
    - [13.1. Resource based long running operations (RELO)](#131-resource-based-long-running-operations-relo)
    - [13.2. Stepwise long running operations](#132-stepwise-long-running-operations)
      - [13.2.1. PUT](#1321-put)
      - [13.2.2. POST](#1322-post)
      - [13.2.3. POST, hybrid model](#1323-post-hybrid-model)
      - [13.2.4. Operations resource](#1324-operations-resource)
      - [13.2.5. Operation resource](#1325-operation-resource)
        - [Percent complete](#percent-complete)
        - [Target resource location](#target-resource-location)
      - [13.2.6. Operation tombstones](#1326-operation-tombstones)
      - [13.2.7. The typical flow, polling](#1327-the-typical-flow-polling)
        - [Example of the typical flow, polling](#example-of-the-typical-flow-polling)
      - [13.2.8. The typical flow, push notifications](#1328-the-typical-flow-push-notifications)
        - [Example of the typical flow, push notifications existing subscription](#example-of-the-typical-flow-push-notifications-existing-subscription)
      - [13.2.9. Retry-After](#1329-retry-after)
    - [13.3. Retention policy for operation results](#133-retention-policy-for-operation-results)
  - [14. Throttling, Quotas, and Limits](#14-throttling-quotas-and-limits)
    - [14.1. Principles](#141-principles)
    - [14.2. Return Codes (429 vs 503)](#142-return-codes-429-vs-503)
    - [14.3. Retry-After and RateLimit Headers](#143-retry-after-and-ratelimit-headers)
    - [14.4. Service Guidance](#144-service-guidance)
      - [14.4.1. Responsiveness](#1441-responsiveness)
      - [14.4.2. Rate Limits and Quotas](#1442-rate-limits-and-quotas)
      - [14.4.3. Overloaded services](#1443-overloaded-services)
      - [14.4.4. Example Response](#1444-example-response)
    - [14.5. Caller Guidance](#145-caller-guidance)
    - [14.6. Handling callers that ignore Retry-After headers](#146-handling-callers-that-ignore-retry-after-headers)
  - [15. Push notifications via webhooks](#15-push-notifications-via-webhooks)
    - [15.1. Scope](#151-scope)
    - [15.2. Principles](#152-principles)
    - [15.3. Types of subscriptions](#153-types-of-subscriptions)
    - [15.4. Call sequences](#154-call-sequences)
    - [15.5. Verifying subscriptions](#155-verifying-subscriptions)
    - [15.6. Receiving notifications](#156-receiving-notifications)
      - [15.6.1. Notification payload](#1561-notification-payload)
    - [15.7. Managing subscriptions programmatically](#157-managing-subscriptions-programmatically)
      - [15.7.1. Creating subscriptions](#1571-creating-subscriptions)
      - [15.7.2. Updating subscriptions](#1572-updating-subscriptions)
      - [15.7.3. Deleting subscriptions](#1573-deleting-subscriptions)
      - [15.7.4. Enumerating subscriptions](#1574-enumerating-subscriptions)
    - [15.8. Security](#158-security)
  - [16. Unsupported requests](#16-unsupported-requests)
    - [16.1. Essential guidance](#161-essential-guidance)
    - [16.2. Feature allow list](#162-feature-allow-list)
      - [16.2.1. Error response](#1621-error-response)
  - [17. Naming guidelines](#17-naming-guidelines)
    - [17.1. Approach](#171-approach)
    - [17.2. Casing](#172-casing)
    - [17.3. Names to avoid](#173-names-to-avoid)
    - [17.4. Forming compound names](#174-forming-compound-names)
    - [17.5. Identity properties](#175-identity-properties)
    - [17.6. Date and time properties](#176-date-and-time-properties)
    - [17.7. Name properties](#177-name-properties)
    - [17.8. Collections and counts](#178-collections-and-counts)
    - [17.9. Common property names](#179-common-property-names)
  - [18. Appendix](#18-appendix)
    - [18.1. Sequence diagram notes](#181-sequence-diagram-notes)
      - [18.1.1. Push notifications, per user flow](#1811-push-notifications-per-user-flow)
      - [18.1.2. Push notifications, firehose flow](#1812-push-notifications-firehose-flow)

<!-- /TOC -->

## 3. Introduction
Developers access most Microsoft Cloud Platform resources via HTTP interfaces.
Although each service typically provides language-specific frameworks to wrap their APIs, all of their operations eventually boil down to HTTP requests.
Microsoft must support a wide range of clients and services and cannot rely on rich frameworks being available for every development environment.
Thus, a goal of these guidelines is to ensure Microsoft REST APIs can be easily and consistently consumed by any client with basic HTTP support.

To provide the smoothest possible experience for developers, it's important to have these APIs follow consistent design guidelines, thus making using them easy and intuitive.
This document establishes the guidelines to be followed by Microsoft REST API developers for developing such APIs consistently.

The benefits of consistency accrue in aggregate as well; consistency allows teams to leverage common code, patterns, documentation and design decisions.

These guidelines aim to achieve the following:
- Define consistent practices and patterns for all API endpoints across Microsoft.
- Adhere as closely as possible to accepted REST/HTTP best practices in the industry at-large. [\*]
- Make accessing Microsoft Services via REST interfaces easy for all application developers.
- Allow service developers to leverage the prior work of other services to implement, test and document REST endpoints defined consistently.
- Allow for partners (e.g., non-Microsoft entities) to use these guidelines for their own REST endpoint design.

[\*] Note: The guidelines are designed to align with building services which comply with the REST architectural style, though they do not address or require building services that follow the REST constraints.
The term "REST" is used throughout this document to mean services that are in the spirit of REST rather than adhering to REST by the book.*

### 3.1. Recommended reading
Understanding the philosophy behind the REST Architectural Style is recommended for developing good HTTP-based services.
If you are new to RESTful design, here are some good resources:

[REST on Wikipedia][rest-on-wikipedia] -- Overview of common definitions and core ideas behind REST.

[REST Dissertation][fielding] -- The chapter on REST in Roy Fielding's dissertation on Network Architecture, "Architectural Styles and the Design of Network-based Software Architectures"

[RFC 7231][rfc-7231] -- Defines the specification for HTTP/1.1 semantics, and is considered the authoritative resource.

[REST in Practice][rest-in-practice] -- Book on the fundamentals of REST.

## 4. Interpreting the guidelines
### 4.1. Application of the guidelines
These guidelines are applicable to any REST API exposed publicly by Microsoft or any partner service.
Private or internal APIs SHOULD also try to follow these guidelines because internal services tend to eventually be exposed publicly.
 Consistency is valuable to not only external customers but also internal service consumers, and these guidelines offer best practices useful for any service.

There are legitimate reasons for exemption from these guidelines.
Obviously, a REST service that implements or must interoperate with some externally defined REST API must be compatible with that API and not necessarily these guidelines.
Some services MAY also have special performance needs that require a different format, such as a binary protocol.

### 4.2. Guidelines for existing services and versioning of services
We do not recommend making a breaking change to a service that predates these guidelines simply for the sake of compliance.
The service SHOULD try to become compliant at the next version release when compatibility is being broken anyway.
When a service adds a new API, that API SHOULD be consistent with the other APIs of the same version.
So if a service was written against version 1.0 of the guidelines, new APIs added incrementally to the service SHOULD also follow version 1.0. The service can then upgrade to align with the latest version of the guidelines at the service's next major release.

### 4.3. Requirements language
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119][rfc-2119].

### 4.4. License

This work is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

## 5. Taxonomy
As part of onboarding to Microsoft REST API Guidelines, services MUST comply with the taxonomy defined below.

### 5.1. Errors
Errors, or more specifically Service Errors, are defined as a client passing invalid data to the service and the service _correctly_  rejecting that data.
Examples include invalid credentials, incorrect parameters, unknown version IDs, or similar.
These are generally "4xx" HTTP error codes and are the result of a client passing incorrect or invalid data.

Errors do _not_ contribute to overall API availability.

### 5.2. Faults
Faults, or more specifically Service Faults, are defined as the service failing to correctly return in response to a valid client request.
These are generally "5xx" HTTP error codes.

Faults _do_ contribute to the overall API availability.

Calls that fail due to rate limiting or quota failures MUST NOT count as faults.
Calls that fail as the result of a service fast-failing requests (often for its own protection) do count as faults.

### 5.3. Latency
Latency is defined as how long a particular API call takes to complete, measured as closely to the client as possible.
This metric applies to both synchronous and asynchronous APIs in the same way.
For long running calls, the latency is measured on the initial request and measures how long that call (not the overall operation) takes to complete.

### 5.4. Time to complete
Services that expose long operations MUST track "Time to Complete" metrics around those operations.

### 5.5. Long running API faults
For a Long Running API, it's possible for both the initial request which begins the operation and the request which retrieves the results to technically work (each passing back a 200) but for the underlying operation to have failed.
Long Running faults MUST roll up as faults into the overall Availability metrics.

## 6. Client guidance
To ensure the best possible experience for clients talking to a REST service, clients SHOULD adhere to the following best practices:

### 6.1. Ignore rule
For loosely coupled clients where the exact shape of the data is not known before the call, if the server returns something the client wasn't expecting, the client MUST safely ignore it.

Some services MAY add fields to responses without changing versions numbers.
Services that do so MUST make this clear in their documentation and clients MUST ignore unknown fields.

### 6.2. Variable order rule
Clients MUST NOT rely on the order in which data appears in JSON service responses.
For example, clients SHOULD be resilient to the reordering of fields within a JSON object.
When supported by the service, clients MAY request that data be returned in a specific order.
For example, services MAY support the use of the _$orderBy_ querystring parameter to specify the order of elements within a JSON array.
Services MAY also explicitly specify the ordering of some elements as part of the service contract.
For example, a service MAY always return a JSON object's "type" information as the first field in an object to simplify response parsing on the client.
Clients MAY rely on ordering behavior explicitly identified by the service.

### 6.3. Silent fail rule
Clients requesting OPTIONAL server functionality (such as optional headers) MUST be resilient to the server ignoring that particular functionality.

## 7. Consistency fundamentals
### 7.1. URL structure
Humans SHOULD be able to easily read and construct URLs.

This facilitates discovery and eases adoption on platforms without a well-supported client library.

An example of a well-structured URL is:

```
https://api.contoso.com/v1.0/people/jdoe@contoso.com/inbox
```

An example URL that is not friendly is:

```
https://api.contoso.com/EWS/OData/Users('jdoe@microsoft.com')/Folders('AAMkADdiYzI1MjUzLTk4MjQtNDQ1Yy05YjJkLWNlMzMzYmIzNTY0MwAuAAAAAACzMsPHYH6HQoSwfdpDx-2bAQCXhUk6PC1dS7AERFluCgBfAAABo58UAAA=')
```

A frequent pattern that comes up is the use of URLs as values.
Services MAY use URLs as values.
For example, the following is acceptable:

```
https://api.contoso.com/v1.0/items?url=https://resources.contoso.com/shoes/fancy
```

### 7.2. URL length
The HTTP 1.1 message format, defined in RFC 7230, in section [3.1.1][rfc-7230-3-1-1], defines no length limit on the Request Line, which includes the target URL.
From the RFC:

> HTTP does not place a predefined limit on the length of a
   request-line. [...] A server that receives a request-target longer than any URI it wishes to parse MUST respond
   with a 414 (URI Too Long) status code.

Services that can generate URLs longer than 2,083 characters MUST make accommodations for the clients they wish to support.
Here are some sources for determining what target clients support:

 * [https://stackoverflow.com/a/417184](https://stackoverflow.com/a/417184)
 * [https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/](https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/)

Also note that some technology stacks have hard and adjustable URL limits, so keep this in mind as you design your services.

### 7.3. Canonical identifier
In addition to friendly URLs, resources that can be moved or be renamed SHOULD expose a URL that contains a unique stable identifier.
It MAY be necessary to interact with the service to obtain a stable URL from the friendly name for the resource, as in the case of the "/my" shortcut used by some services.

The stable identifier is not required to be a GUID.

An example of a URL containing a canonical identifier is:

```
https://api.contoso.com/v1.0/people/7011042402/inbox
```

### 7.4. Supported methods
Operations MUST use the proper HTTP methods whenever possible, and operation idempotency MUST be respected.
HTTP methods are frequently referred to as the HTTP verbs.
The terms are synonymous in this context, however the HTTP specification uses the term method.

Below is a list of methods that Microsoft REST services SHOULD support.
Not all resources will support all methods, but all resources using the methods below MUST conform to their usage.

Method  | Description                                                                                                                | Is Idempotent
------- | -------------------------------------------------------------------------------------------------------------------------- | -------------
GET     | Return the current value of an object                                                                                      | True
PUT     | Replace an object, or create a named object, when applicable                                                               | True
DELETE  | Delete an object                                                                                              
Download .txt
gitextract_y88h3vd0/

├── .github/
│   └── CODEOWNERS
├── CONTRIBUTING.md
├── Guidelines.md
├── README.md
├── SECURITY.md
├── azure/
│   ├── .markdownlint.json
│   ├── ConsiderationsForServiceDesign.md
│   ├── Guidelines.md
│   ├── README.md
│   └── VersioningGuidelines.md
├── graph/
│   ├── Guidelines-deprecated.md
│   ├── GuidelinesGraph.md
│   ├── articles/
│   │   ├── collections.md
│   │   ├── coreTypes.md
│   │   ├── deprecation.md
│   │   ├── errorResponses.md
│   │   ├── filter-as-segment.md
│   │   ├── naming.md
│   │   └── nullable.md
│   └── patterns/
│       ├── PatternDescriptionTemplate.md
│       ├── alternate-key.md
│       ├── antiPatternTemplate.md
│       ├── change-tracking.md
│       ├── default-properties.md
│       ├── dictionary-client-guidance.md
│       ├── dictionary.md
│       ├── enums.md
│       ├── evolvable-enums.md
│       ├── facets.md
│       ├── flat-bag.md
│       ├── long-running-operations.md
│       ├── namespace.md
│       ├── navigation-property.md
│       ├── operations.md
│       ├── subsets.md
│       ├── subtypes.md
│       ├── upsert.md
│       └── viewpoint.md
└── license.txt
Condensed preview — 39 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (558K chars).
[
  {
    "path": ".github/CODEOWNERS",
    "chars": 199,
    "preview": "# These are the set of folks who should review PRs on the azureRestUpdates branch.\n#*  @microsoft/azure-api-stewardship-"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4412,
    "preview": "# Contributing to the Microsoft REST API Guidelines\nThe Microsoft REST API Guidelines is a Microsoft-wide initiative to "
  },
  {
    "path": "Guidelines.md",
    "chars": 1039,
    "preview": "> # NOTICE TO READERS\n> This document has been deprecated and has been moved to the [Microsoft REST API Guidelines depre"
  },
  {
    "path": "README.md",
    "chars": 2087,
    "preview": "# Microsoft REST API Guidelines\nThank you for your interest in the Microsoft REST API Guidelines. If you have landed her"
  },
  {
    "path": "SECURITY.md",
    "chars": 2757,
    "preview": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products an"
  },
  {
    "path": "azure/.markdownlint.json",
    "chars": 221,
    "preview": "{\n  \"default\": true,\n  \"MD012\": {\n    \"maximum\": 2\n  },\n  \"MD013\": {\n    \"line_length\": 500\n  },\n  \"MD022\": false,\n  \"MD"
  },
  {
    "path": "azure/ConsiderationsForServiceDesign.md",
    "chars": 51857,
    "preview": "# Considerations for Service Design\n\n<!-- cspell:ignore autorest, etag, idempotency, maxpagesize, openapi -->\n<!-- markd"
  },
  {
    "path": "azure/Guidelines.md",
    "chars": 108386,
    "preview": "# Microsoft Azure REST API Guidelines\n\n<!-- cspell:ignore autorest, BYOS, etag, idempotency, maxpagesize, innererror, tr"
  },
  {
    "path": "azure/README.md",
    "chars": 1659,
    "preview": "# Azure REST API Guidance\nWhen building software components that will be used by developers to build other software, pro"
  },
  {
    "path": "azure/VersioningGuidelines.md",
    "chars": 2842,
    "preview": "# Azure Versioning Guidelines\n\n## History\n\n<details>\n  <summary>Expand change history</summary>\n\n| Date        | Notes  "
  },
  {
    "path": "graph/Guidelines-deprecated.md",
    "chars": 142446,
    "preview": "\n> # DEPRECATION NOTICE TO READERS\n>\n> This document is being deprecated and merged with the  [Microsoft Graph REST API "
  },
  {
    "path": "graph/GuidelinesGraph.md",
    "chars": 37868,
    "preview": "# Microsoft Graph REST API Guidelines\n\nTable of contents\n\n- [Microsoft Graph REST API Guidelines](#microsoft-graph-rest-"
  },
  {
    "path": "graph/articles/collections.md",
    "chars": 20710,
    "preview": "# Collections\n\n## 1. Item keys\n\nServices SHOULD support durable identifiers for each item in the collection, and that id"
  },
  {
    "path": "graph/articles/coreTypes.md",
    "chars": 3595,
    "preview": "# Core Types\n\n## Overview\n\nTypes exist in Microsoft Graph which are highly-connected/central to the Microsoft Graph ecos"
  },
  {
    "path": "graph/articles/deprecation.md",
    "chars": 2445,
    "preview": "# Deprecation guidelines\n\nIf your API requires the introduction of breaking changes, you must add Revisions annotations "
  },
  {
    "path": "graph/articles/errorResponses.md",
    "chars": 7182,
    "preview": "# Error condition responses\n\nFor non-success conditions, developers SHOULD be able to write one piece of code that handl"
  },
  {
    "path": "graph/articles/filter-as-segment.md",
    "chars": 2653,
    "preview": "# Filter as segment\n\nThere is an [OData feature](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-con"
  },
  {
    "path": "graph/articles/naming.md",
    "chars": 4462,
    "preview": "# Naming\n\n## 1. Approach\n\nNaming policies should aid developers in discovering functionality without having to constantl"
  },
  {
    "path": "graph/articles/nullable.md",
    "chars": 9802,
    "preview": "# Nullable Properties\n\nA nullable property means *only* that the property may have `null` as a value; the \"nullability\" "
  },
  {
    "path": "graph/patterns/PatternDescriptionTemplate.md",
    "chars": 555,
    "preview": "# Pattern name\n\nMicrosoft Graph API Design Pattern\n\n*Provide a short description of the pattern.*\n\n\n## Problem\n\n*Describ"
  },
  {
    "path": "graph/patterns/alternate-key.md",
    "chars": 6240,
    "preview": "# Alternate key\n\nMicrosoft Graph API Design Pattern\n\n*The alternate key pattern provides the ability to query for a sing"
  },
  {
    "path": "graph/patterns/antiPatternTemplate.md",
    "chars": 898,
    "preview": "\n# Antipattern name\n\n*name with a negative connotation*\n\n*Example: Flatbag of properties* \n\n## Description\n\n*Example: Th"
  },
  {
    "path": "graph/patterns/change-tracking.md",
    "chars": 12577,
    "preview": "# Change tracking\n\nMicrosoft Graph API Design Pattern\n\n*The change tracking pattern provides the ability for API consume"
  },
  {
    "path": "graph/patterns/default-properties.md",
    "chars": 10017,
    "preview": "# Default properties\n\nMicrosoft Graph API Design Pattern\n\n*The default properties pattern allows API producers to omit s"
  },
  {
    "path": "graph/patterns/dictionary-client-guidance.md",
    "chars": 2406,
    "preview": "# Dictionary types\n\n> **Note:** This document will be moved into a central client guidance document in the future.\n\n*The"
  },
  {
    "path": "graph/patterns/dictionary.md",
    "chars": 8082,
    "preview": "# Dictionary\n\nMicrosoft Graph API Design Pattern\n\n_The dictionary type provides the ability to create a set key/value pa"
  },
  {
    "path": "graph/patterns/enums.md",
    "chars": 6289,
    "preview": "### Enums\r\n\r\nIn OData, enums represent a subset of the nominal type they rely on, and are especially useful in cases whe"
  },
  {
    "path": "graph/patterns/evolvable-enums.md",
    "chars": 16450,
    "preview": "# Evolvable enums\n\nMicrosoft Graph API Design Pattern\n\n*The evolvable enums pattern allows API producers to extend enume"
  },
  {
    "path": "graph/patterns/facets.md",
    "chars": 4923,
    "preview": "# Facets\n\nMicrosoft Graph API Design Pattern\n\n*A frequent pattern in Microsoft Graph is to model multiple variants of a "
  },
  {
    "path": "graph/patterns/flat-bag.md",
    "chars": 3294,
    "preview": "# Flat bag of properties\n\nMicrosoft Graph API Design Pattern\n\n*A known pattern in Microsoft Graph is to model multiple v"
  },
  {
    "path": "graph/patterns/long-running-operations.md",
    "chars": 9420,
    "preview": "# Long running operations\n\nMicrosoft Graph API Design Pattern\n\n*The long running operations (LRO) pattern provides the a"
  },
  {
    "path": "graph/patterns/namespace.md",
    "chars": 5526,
    "preview": "# Namespace\n\nMicrosoft Graph API Design Pattern\n\n*The namespace pattern provides the ability to organize resource defini"
  },
  {
    "path": "graph/patterns/navigation-property.md",
    "chars": 8673,
    "preview": "# Navigation Property\n\nMicrosoft Graph API Design Pattern\n\n*A navigation property is used to identify a relationship bet"
  },
  {
    "path": "graph/patterns/operations.md",
    "chars": 6650,
    "preview": "# Operations\n\nMicrosoft Graph API Design Pattern\n\n*The operations pattern provides the ability to model a change that mi"
  },
  {
    "path": "graph/patterns/subsets.md",
    "chars": 8677,
    "preview": "# Modeling collection subsets\n\nMicrosoft Graph API Design Pattern\n\n*The modeling collection subsets pattern is the model"
  },
  {
    "path": "graph/patterns/subtypes.md",
    "chars": 7130,
    "preview": "# Type hierarchy\n\nMicrosoft Graph API Design Pattern\n\n*A frequent pattern in Microsoft Graph is to have a small type hie"
  },
  {
    "path": "graph/patterns/upsert.md",
    "chars": 8933,
    "preview": "# Upsert\n\nMicrosoft Graph API Design Pattern\n\n*The `Upsert` pattern is a non-destructive idempotent operation using a cl"
  },
  {
    "path": "graph/patterns/viewpoint.md",
    "chars": 5764,
    "preview": "# Viewpoint\n\nMicrosoft Graph API Design Pattern\n\n\n*The viewpoint pattern provides the ability to manage properties of a "
  },
  {
    "path": "license.txt",
    "chars": 251,
    "preview": "This work is licensed under the Creative Commons Attribution 4.0 International License.\nTo view a copy of this license, "
  }
]

About this extraction

This page contains the full source code of the microsoft/api-guidelines GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 39 files (526.7 KB), approximately 123.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!