[
  {
    "path": ".github/CODEOWNERS",
    "content": "# These are the set of folks who should review PRs on the azureRestUpdates branch.\n#*  @microsoft/azure-api-stewardship-board @Azure/api-stewardship-board\n/graph/ @microsoft/graphguidelinesapprovers\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to the Microsoft REST API Guidelines\nThe 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.\n\nTo 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.\n\nPlease 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.\n- [Creating issues](#creating-issues)\n- [Recommended setup for contributing](#recommended-setup-for-contributing)\n- [Documentation styleguide](#documentation-styleguide)\n- [Commit messages](#commit-messages)\n- [Pull requests](#pull-requests)\n\n## Creating issues\n- You can [create an issue][new-issue], but before doing that please read the bullets below and include as many details as possible.\n- Perform a [cursory search][issue-search] to see if a similar issue has already been submitted.\n- Reference the version of the Microsoft REST API Guidelines you are using.\n- Include the guidance you expected and other places you've seen that guidance, e.g. [White House Web API Standards][white-house-api-guidelines].\n- Include sample requests and responses whenever possible.\n\n### Related repositories\nThis is the repository for Microsoft REST API Guidelines documentation only. Please ensure that you are opening issues in the right repository.\n\n## Recommended setup for contributing\n- Fork this repository on GitHub\n- Install [Git][git] to your computer and clone your new forked repository\n- Install [Atom][atom], [VS Code][vscode], or your favorite editor\n- Install [markdown-toc package][markdown-toc]\n\n## Documentation styleguide\n- Use [GitHub-flavored markdown][gfm]\n- Use syntax-highlighted examples liberally\n- Trim trailing empty lines from HTTP requests\n- Retain only essential headers for understanding the example\n- Use valid (e.g., member names quoted), pretty-printed JSON with a 2 space indent\n- Minimize JSON payloads by using ellipses\n- Write one sentence per line.\n\n### Example\n#### Request\n\n```http\nGET http://services.odata.org/V4/TripPinServiceRW/People HTTP/1.1\nAccept: application/json\n```\n\n#### Response\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"@nextLink\":\"http://services.odata.org/V4/TripPinServiceRW/People?$skiptoken=8\",\n  \"value\":[\n    {\n      \"userName\":\"russellwhyte\",\n      \"firstName\":\"Russell\",\n      \"lastName\":\"Whyte\",\n      \"emails\":[\n        \"Russell@example.com\",\n        \"Russell@contoso.com\"\n      ],\n      \"addressInfo\":[\n        {\n          \"address\":\"187 Suffolk Ln.\",\n          \"city\":{\n            \"countryRegion\":\"United States\",\n            \"name\":\"Boise\",\n            \"region\":\"ID\"\n          }\n        }\n      ],\n      \"gender\":\"Male\",\n    },\n    ...\n  ]\n}\n```\n\n## Commit messages\n- Use the present tense: \"Change ...\", not \"Changed ...\"\n- Use the imperative mood: \"Change ...\", not \"Changes ...\"\n- Limit the first line to 72 characters or less\n- Reference issues and pull requests liberally\n\n## Pull requests\nPull 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].\n\nBe prepared to address feedback on your pull request and iterate if necessary.\n\n[code-of-conduct]: https://opensource.microsoft.com/codeofconduct/\n[new-issue]: https://github.com/Microsoft/api-guidelines/issues/new\n[issue-search]: https://github.com/Microsoft/api-guidelines/issues\n[white-house-api-guidelines]: https://github.com/WhiteHouse/api-standards/blob/master/README.md\n[topic-branch]: https://www.git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#Topic-Branches\n[gfm]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown\n[github-flow-guide]: https://guides.github.com/introduction/flow/\n[atom-beautify]: https://atom.io/packages/atom-beautify\n[atom]: https://atom.io/\n[markdown-toc]: https://atom.io/packages/markdown-toc\n[vscode]: https://code.visualstudio.com/\n[git]: https://git-scm.com/\n"
  },
  {
    "path": "Guidelines.md",
    "content": "> # NOTICE TO READERS\n> 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.\n> \n> ## **Guidance for Azure service teams**\n> 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.\n> \n> ## **Guidance for Microsoft Graph service teams**\n> 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.\n\n---\n"
  },
  {
    "path": "README.md",
    "content": "# Microsoft REST API Guidelines\nThank 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!\nWe 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.\n\n### Guidance for Azure service teams\nAzure 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.\n\n### Guidance for Microsoft Graph service teams\nGraph 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.\n\n[![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/)\n\n## Code of Conduct\nThis 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.\n\n## This repository\nThis 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].\n\n[contribution-guidance]: CONTRIBUTING.md\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->\n\n## Security\n\nMicrosoft 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/).\n\nIf 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.\n\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.**\n\nInstead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).\n\nIf 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).\n\nYou 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). \n\nPlease 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:\n\n  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)\n  * Full paths of source file(s) related to the manifestation of the issue\n  * The location of the affected source code (tag/branch/commit or direct URL)\n  * Any special configuration required to reproduce the issue\n  * Step-by-step instructions to reproduce the issue\n  * Proof-of-concept or exploit code (if possible)\n  * Impact of the issue, including how an attacker might exploit the issue\n\nThis information will help us triage your report more quickly.\n\nIf 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.\n\n## Preferred Languages\n\nWe prefer all communications to be in English.\n\n## Policy\n\nMicrosoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "azure/.markdownlint.json",
    "content": "{\n  \"default\": true,\n  \"MD012\": {\n    \"maximum\": 2\n  },\n  \"MD013\": {\n    \"line_length\": 500\n  },\n  \"MD022\": false,\n  \"MD031\": false,\n  \"MD032\": false,\n  \"MD033\": {\n    \"allowed_elements\": [ \"sup\" ]\n  },\n  \"MD036\": false\n}"
  },
  {
    "path": "azure/ConsiderationsForServiceDesign.md",
    "content": "# Considerations for Service Design\n\n<!-- cspell:ignore autorest, etag, idempotency, maxpagesize, openapi -->\n<!-- markdownlint-disable MD033 -->\n\n## History\n\n| Date        | Notes                                                          |\n| ----------- | -------------------------------------------------------------- |\n| 2024-Mar-17 | Updated LRO guidelines                                         |\n| 2024-Jan-17 | Added guidelines on returning string offsets & lengths         |\n| 2022-Jul-15 | Update guidance on long-running operations                     |\n| 2022-Feb-01 | Updated error guidance                                         |\n| 2021-Sep-11 | Add long-running operations guidance                           |\n| 2021-Aug-06 | Updated Azure REST Guidelines per Azure API Stewardship Board. |\n\n## Introduction\n\nGreat 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_.\n\nThis 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.\nFor 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.\n\nAzure 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.\n\nIt is critically important to design your service to avoid disrupting users as the API evolves:\n\n<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.\n\n<a href=\"#principles-compatibility\" name=\"principles-compatibility\">:white_check_mark:</a> **DO** ensure that customer workloads never break\n\n<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**\n\n## Azure Management Plane vs Data Plane\n_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._\n\nA **management plane** API is implemented through the Azure Resource Manager (ARM) and is used to provision and control the operational state of resources.\nA **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.\nAlthough, 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).\n\n## Start with the Developer Experience\nA 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.\n\nFollow these practices to create clear names for your abstractions:\n- 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.\n- Don't include \"throwaway\" words in names, like \"response\", \"object\", \"payload\", etc.\n- 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.\n- Pick one word/term out of a set of synonyms and stick to it.\n\nIt 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:\n- Building apps that consume the API\n- Hold reviews and share what is learned with your team\n- Get customer feedback from API previews\n- Thinking about the code that a customer writes both before and after an HTTP operation\n- Initializing and reading from the data structures your service requires\n- Thinking about which errors are recoverable at runtime as opposed to indicating a bug in the customer code that must be fixed\n\nThe 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.\n\n## Focus on Hero Scenarios\nIt 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.\n\n_For this reason, it is **much better** to ship with fewer features and only add new features over time as required by customers._\n\nFocusing 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.\n\n<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.\n\n<a href=\"#hero-scenarios-examples\" name=\"hero-scenarios-examples\">:white_check_mark:</a> **DO** provide example code demonstrating the \"Hero Scenarios\".\n\n<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.\n\n<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.\n\n<a href=\"#hero-scenarios-yagni\" name=\"hero-scenarios-yagni\">:no_entry:</a> **DO NOT** proactively add APIs for speculative features customers might want.\n\n### Start with your API Definition\nUnderstanding 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.\n\n<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.\n\n## Design for Change Resiliency\nAs 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.\n\n<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.\n\n<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.\n\n## Use Good Names\n\nGood names for resources, properties, operations, and parameters are essential to a great developer experience.\n\nResources are described by nouns. Resource and property names must be descriptive and easy for customers to understand.\nUse names that correspond to user scenarios rather than service implementation details, e.g. \"Diagnosis\" and not \"TreeLeafNode\".\nNames should convey the value's purpose and not simply describe its structure, e.g. \"ConfigurationSetting\" and not \"KeyValuePair\".\nEase 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.\n\nNames should aid developers in discovering functionality without having to constantly refer to documentation.\nUse common patterns and standard conventions to aid developers in correctly guessing common property names and meanings.\nUse verbose naming patterns and avoid abbreviations other than\nwell-known acronyms in your service domain.\n\n<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.\n\n### Recommended Naming Conventions\n\nThe following are recommended naming conventions for Azure services:\n\n<a href=\"#naming-collections\" name=\"naming-collections\">:white_check_mark:</a> **DO** name collections as plural nouns or plural noun phrases using correct English.\n\n<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.\n\n<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.\n\nFor example, `collectedItems` not `itemsCollected`\n\n<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).\n\nFor example, `nextUrl` not `nextURL`.\n\n<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.\n\nFor example, `createdAt` not `created` or `createdDateTime`.\n\n<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.\n\n<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.\n\nFor example, `expirationDays` as `int` and not `expiration` as `date-time`.\n\n<a href=\"#naming-brand-names\" name=\"naming-brand-names\">:warning:</a> **YOU SHOULD NOT** use brand names in resource or property names.\n\n<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\".\n\n<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).\n\n<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\".\n\n<a href=\"#naming-avoid-redundancy\" name=\"naming-avoid-redundancy\">:no_entry:</a> **DO NOT** use redundant words in names.\n\nFor example, `/phones/number` and not `phone/phoneNumber`.\n\n### Common names\n\nThe following are recommended names for properties that match the associated description:\n\n| Name | Description |\n|------------- | --- |\n| createdAt | The date and time the resource was created. |\n| lastModifiedAt | The date and time the resource was last modified. |\n| deletedAt | The date and time the resource was deleted. |\n| kind   | The discriminator value for a polymorphic resource |\n| etag | The entity tag used for optimistic concurrency control, when included as a property of a resource. |\n\n### `name` vs `id`\n\n<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.\n\nThis holds even in the case where the identifier is assigned by the user with a PUT/PATCH method.\n\n## Use Previews to Iterate\nBefore 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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n## Communicate Deprecations\nAs 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.\nAzure 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.\n\nHowever, 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.\nThis 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.\n\n## Avoid Surprises\nA 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.\n\nOne common area of friction for developers is _polymorphism_ -- where a value may have any of several types or structures.\nPolymorphism 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.\n\nCollections 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.\n\nAn important consideration when defining a new service is support for pagination.\n\n<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.\n\nAnother consideration for collections is support for sorting the set of returned items with the _orderby_ query parameter.\nSorting 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.\n\n<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).\n\nAnother 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.\nHTTP 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.\nSee the [HTTP Request / Response Pattern section of the Guidelines](./Guidelines.md#http-request--response-pattern) for detailed guidance on making operations idempotent.\n\n## Action Operations\n\nMost 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.\n\nIt 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:\n1) constrain user-specified resource ids to allow only certain characters, such as alphanumeric and '-' or '_', and\n2) use a special character not in the set of valid characters for resource names to distinguish the \"action\" in the path.\n\nIn Azure we recommend distinguishing action operations by appending a ':' followed by an action verb to the final path segment.  E.g.\n```text\nhttps://.../<resource-collection>/<resource-id>:<action>?<input parameters>\n```\n\nOther patterns are possible. The key consideration is to ensure that the path for an action operation\ncannot collide with a resource path that contains user-specified resource ids.\n\n## Long-Running Operations\n\nLong-running operations (LROs) are an API design pattern that should be used when the processing of\nan operation may take a significant amount of time -- longer than a client will want to block\nwaiting for the result.\n\nThe request that initiates a long-running operation returns a response that points to or embeds\na _status monitor_, which is an ephemeral resource that will track the status and final result of the operation.\nThe status monitor resource is distinct from the target resource (if any) and specific to the individual\noperation request.\n\nThere are four types of LROs allowed in Azure REST APIs:\n\n1. An LRO to create or replace a resource that involves additional long-running processing.\n2. An LRO to delete a resource.\n3. An LRO to perform an action on or with an existing resource (or resource collection).\n4. An LRO to perform an action not related to an existing resource (or resource collection).\n\nThe following sections describe these patterns in detail.\n\n### Create or replace a resource requiring additional long-running processing\n<a href=\"#put-with-additional-long-running-processing\"></a> <!-- Preserve anchor of previous heading -->\n\nA special case of long-running operations that occurs often is a PUT operation to create or replace a resource\nthat involves some additional long-running processing.\nOne example is a resource that requires physical resources (e.g. servers) to be \"provisioned\" to make the resource functional.\n\nIn this case:\n- The operation must use the PUT method (NOTE: PATCH is never allowed here)\n- The URL identifies the resource being created or replaced.\n- The request and response body have identical schemas & represent the resource.\n- The request may contain an `Operation-Id` header that the service will use as\nthe ID of the status monitor created for the operation.\n- If the `Operation-Id` matches an existing operation and the request content is the same,\ntreat as a retry and return the same response as the earlier request.\nOtherwise fail the request with a `409-Conflict`.\n\n```text\nPUT /items/FooBar&api-version=2022-05-01\nOperation-Id: 22\n\n{\n   \"prop1\": 555,\n   \"prop2\": \"something\"\n}\n```\n\nIn this case the response to the initial request is a `201 Created` to indicate that\nthe resource has been created or `200 OK` when the resource was replaced.\nThe response body should be a representation of the resource that was created,\nand should include a `status` field indicating the current status of the resource.\nA status monitor is created to track the additional processing and the ID of the status monitor\nis returned in the `Operation-Id` header of the response.\nThe response must also include an `Operation-Location` header for backward compatibility.\nIf the resource supports ETags, the response may contain an `etag` header and possibly an `etag` property in the resource.\n\n```text\nHTTP/1.1 201 Created\nOperation-Id: 22\nOperation-Location: https://items/operations/22\netag: \"123abc\"\n\n{\n  \"id\": \"FooBar\",\n  \"status\": \"Provisioning\",\n  \"prop1\": 555,\n  \"prop2\": \"something\",\n  \"etag\": \"123abc\"\n}\n```\n\nThe client will issue a GET to the status monitor to obtain the status of the operation performing the additional processing.\n\n```text\nGET https://items/operations/22?api-version=2022-05-01\n```\n\nWhen the additional processing completes, the status monitor indicates if it succeeded or failed.\n\n```text\nHTTP/1.1 200 OK\n\n{\n   \"id\": \"22\",\n   \"status\": \"Succeeded\"\n}\n```\n\nIf the additional processing failed, the service may delete the original resource if it is not usable in this state,\nbut should clearly document this behavior.\n\n### Long-running delete operation\n\nA long-running delete operation returns a `202 Accepted` with a status monitor which the client uses to determine the outcome of the delete.\n\nThe resource being deleted should remain visible (returned from a GET) until the delete operation completes successfully.\n\nWhen the delete operation completes successfully, a client must be able to create a new resource with the same name without conflicts.\n\nThis diagram illustrates how a long-running DELETE operation is initiated and then how the client\ndetermines it has completed and obtains its results:\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant API Endpoint\n    participant Status Monitor\n    Client->>API Endpoint: DELETE\n    API Endpoint->>Client: HTTP/1.1 202 Accepted<br/>{ \"id\": \"22\", \"status\": \"NotStarted\" }\n    Client->>Status Monitor: GET\n    Status Monitor->>Client: HTTP/1.1 200 OK<br/>Retry-After: 5<br/>{ \"id\": \"22\", \"status\": \"Running\" }\n    Client->>Status Monitor: GET\n    Status Monitor->>Client: HTTP/1.1 200 OK<br/>{ \"id\": \"22\", \"status\": \"Succeeded\" }\n```\n\n1. The client sends the request to initiate the long-running DELETE operation.\nThe request may contain an `Operation-Id` header that the service uses as the ID of the status monitor created for the operation.\n\n2. The service validates the request and initiates the operation processing.\nIf there are any problems with the request, the service responds with a `4xx` status code and error response body.\nOtherwise the service responds with a `202-Accepted` HTTP status code.\nThe response body is the status monitor for the operation including the ID, either from the request header or generated by the service.\nWhen 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\nbefore polling (GETing) the status monitor URL again for an update.\nFor backward compatibility, the response must also include an `Operation-Location` header containing the absolute URL\nof the status monitor resource, including an api-version query parameter.\n\n3. After waiting at least the amount of time specified by the previous response's `Retry-after` header,\nthe client issues a GET request to the status monitor using the ID in the body of the initial response.\nThe GET operation for the status monitor is documented in the REST API definition and the ID\nis the last URL path segment.\n\n4. The status monitor responds with information about the operation including its current status,\nwhich should be represented as one of a fixed set of string values in a field named `status`.\nIf the operation is still being processed, the status field will contain a \"non-terminal\" value, like `NotStarted` or `Running`.\n\n5. 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.\nIf the status is `Failed`, the status monitor resource contains an `error` field with a `code` and `message` that describes the failure.\n\n6. There may be some cases where a long-running DELETE operation can be completed before the response to the initial request.\nIn these cases, the operation should still return a `202 Accepted` with the `status` property set to the appropriate terminal state.\n\n7. The service is responsible for purging the status monitor resource.\nIt should auto-purge the status monitor resource after completion (at least 24 hours).\nThe service may offer DELETE of the status monitor resource due to GDPR/privacy.\n\n### Long-running Action Operations\n\nAn action operation that is also long-running combines the [Action Operations](#action-operations) pattern\nwith the [Long Running Operations](#long-running-operations) pattern.\n\nThe operation is initiated with a POST operation and the operation path ends in `:<action>`.\nA long-running POST should not be used for resource create: use PUT as described above.\nPATCH must never be used for long-running operations: it should be reserved for simple resource updates.\nIf a long-running update is required it should be implemented with POST.\n\n```text\nPOST /<service-or-resource-url>:<action>?api-version=2022-05-01\nOperation-Id: 22\n\n{\n   \"arg1\": 123\n   \"arg2\": \"abc\"\n}\n```\n\nA long-running action operation returns a `202 Accepted` response with the status monitor in the response body.\n\n```text\nHTTP/1.1 202 Accepted\nOperation-Location: https://<status-monitor-endpoint>/22\n\n{\n   \"id\": \"22\",\n   \"status\": \"NotStarted\"\n}\n```\n\nThe client will issue a GET to the status monitor to obtain the status and result of the operation.\n\n```text\nGET https://<status-monitor-endpoint>/22?api-version=2022-05-01\n```\n\nWhen the operation completes successfully, the result (if there is one) will be included in the `result` field of the status monitor.\n\n```text\nHTTP/1.1 200 OK\n\n{\n   \"id\": \"22\",\n   \"status\": \"Succeeded\",\n   \"result\": { ... }\n}\n```\n\nThis diagram illustrates how a long-running action operation is initiated and then how the client\ndetermines it has completed and obtains its results:\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant API Endpoint\n    participant Status Monitor\n    Client->>API Endpoint: POST\n    API Endpoint->>Client: HTTP/1.1 202 Accepted<br/>{ \"id\": \"22\", \"status\": \"NotStarted\" }\n    Client->>Status Monitor: GET\n    Status Monitor->>Client: HTTP/1.1 200 OK<br/>Retry-After: 5<br/>{ \"id\": \"22\", \"status\": \"Running\" }\n    Client->>Status Monitor: GET\n    Status Monitor->>Client: HTTP/1.1 200 OK<br/>{ \"id\": \"22\", \"status\": \"Succeeded\", \"result\": { ... } }\n```\n\n1. The client sends the request to initiate the long-running action operation.\nThe request may contain an `Operation-Id` header that the service uses as the ID of the status monitor created for the operation.\n\n2. The service validates the request and initiates the operation processing.\nIf there are any problems with the request, the service responds with a `4xx` status code and error response body.\nOtherwise the service responds with a `202-Accepted` HTTP status code.\nThe response body is the status monitor for the operation including the ID, either from the request header or generated by the service.\nWhen 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\nbefore polling (GETing) the status monitor URL again for an update.\nFor backward compatibility, the response may also include an `Operation-Location` header containing the absolute URL\nof the status monitor resource, including an api-version query parameter.\n\n3. After waiting at least the amount of time specified by the previous response's `Retry-after` header,\nthe client issues a GET request to the status monitor using the ID in the body of the initial response.\nThe GET operation for the status monitor is documented in the REST API definition and the ID\nis the last URL path segment.\n\n4. The status monitor responds with information about the operation including its current status,\nwhich should be represented as one of a fixed set of string values in a field named `status`.\nIf the operation is still being processed, the status field will contain a \"non-terminal\" value, like `NotStarted` or `Running`.\n\n5. 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.\nIf the status is `Failed`, the status monitor resource contains an `error` field with a `code` and `message` that describes the failure.\nIf the status is `Succeeded`, the operation results (if any) are returned in the `result` field of the status monitor.\n\n6. There may be some cases where a long-running action operation can be completed before the response to the initial request.\nIn these cases, the operation should still return a `202 Accepted` with the `status` property set to the appropriate terminal state.\n\n7. The service is responsible for purging the status monitor resource.\nIt should auto-purge the status monitor resource after completion (at least 24 hours).\nThe service may offer DELETE of the status monitor resource due to GDPR/privacy.\n\n### Long-running action operation not related to a resource\n\nWhen a long-running action operation is not related to a specific resource (a batch operation is one example),\nanother approach is needed.\n\nThis type of LRO should be initiated with a PUT method on a URL that represents the operation to be performed,\nand includes a final path parameter for the user-specified operation ID.\nThe response of the PUT includes a response body containing a representation of the status monitor for the operation\nand an `Operation-Location` response header that contains the absolute URL of the status monitor.\nIn this type of LRO, the status monitor should include any information from the request used to initiate the operation,\nso that a failed operation could be reissued if necessary.\n\nClients will use a GET on the status monitor URL to obtain the status and results of the operation.\nSince the HTTP semantic for PUT is to create a resource, the same schema should be used for the PUT request body,\nthe PUT response body, and the response body of the GET for the status monitor for the operation.\nFor this type of LRO, the status monitor URL should be the same URL as the PUT operation.\n\nThe following examples illustrate this pattern.\n\n```text\nPUT /translate-operations/<operation-id>?api-version=2022-05-01\n\n<JSON body with parameters for the operation>\n```\n\nNote that the client specifies the operation id in the URL path.\n\nA successful response to the PUT operation should have a `201 Created` status and response body\nthat contains a representation of the status monitor _and_ any information from the request used to initiate the operation.\n\nThe service is responsible for purging the status monitor after some period of time,\nbut no earlier than 24 hours after the completion of the operation.\nThe service may offer DELETE of the status monitor resource due to GDPR/privacy.\n\n### Controlling a long-running operation\n\nIt might be necessary to support some control action on a long-running operation, such as cancel.\nThis is implemented as a POST on the status monitor endpoint with `:<action>` added.\n\n```text\nPOST /<status-monitor-endpoint>:cancel?api-version=2022-05-01\n```\n\nA successful response to a control operation should be a `200 OK` with a representation of the status monitor.\n\n```text\nHTTP/1.1 200 OK\n\n{\n   \"id\": \"22\",\n   \"status\": \"Canceled\"\n}\n```\n\n## Errors\nOne 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.\n\nFirst, 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:\n- 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.\n- 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.\n- 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`.\n\nThere are two types of errors returned from your service and customers handle them differently.\n- 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.\n- 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.\n\nYou 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:\n- A `404` status code tells them the blob doesn't exist and the customer can report the error to their users\n- A `BlobNotFound` or `ContainerNotFound` error code will tell them why the blob doesn't exist so they can take steps to recreate it\n\nThe [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.\nImportantly, this means you **changing the HTTP status code or top-level error code for an API is a breaking change**.\nYou 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.\n\nYou 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.\nThe 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.\nYou 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).\n\nYou 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.\n\nBe 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.\nDon'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.\n\nAll 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.\n\nFinally, 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?\nWe 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.\n\n## Pagination\n\nOperations that return a collection of resources must consider pagination.\nThere are hard limits to the payload size of HTTP responses, and when the size of a collection or the resources themselves\ncan grow arbitrarily large there is the risk of exceeding this limit if the operation does not support pagination.\nFurther, adding support for pagination is a breaking change so it should be supported in the initial GA of the service\nif there is any possibility that it will eventually be needed.\n\nThere are two forms of pagination that MAY be supported by RESTful APIs.\nServer-driven paging mitigates against denial-of-service attacks by forcibly paginating a request over multiple response payloads.\nClient-driven paging enables clients to request only the number of resources that it can use at a given time.\nServices should almost always support server-driven paging and may optionally support client-driven paging.\n\n### Server-driven paging\n\nIn server-driven paging, the service includes a `nextLink` property in the response to indicate that additional elements\nexist in the collection.\nThe value of the `nextLink` property should be an opaque absolute URL that will return the next page of results.\nThe absence of a `nextLink` property means that no additional pages are available.\nSince `nextLink` is an opaque URL it should include any query parameters required by the service, including `api-version`.\nThe service should honor a request to a URL derived from `nextLink` by replacing the value for the `apl-version` query parameter\nwith a different but valid api version. The service may reject the request if any other element of `nextLink` was modified.\n\nThe 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.\nAn operation may allow the client to specify a maximum number of items in a response with an optional `maxpagesize` parameter.\nOperations that support `maxpagesize` should return no more than the value specified in `maxpagesize` but may return fewer.\n\n### Client-driven paging\n\nAn operation may support `skip` and `top` query parameters to allow the client to specify an offset into the collection\nand the number of results to return, respectively.\n\nNote that when `top` specifies a value larger than the server-driven paging page size, the response will be paged accordingly.\n\n## Conditional Requests\n\nWhen 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.\nSimilarly, 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.\nBoth of these scenarios can be accomplished with conditional requests, where the client specifies a _precondition_\nfor execution of a request, based on its last modification date or entity tag (\"ETag\").\nAn 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.\n\n### Cache Control\n\nOne 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).\nA client can make a \"conditional GET request\" for the resource, with a precondition header that requests that\ndata be returned only when the version on the service does not match the ETag or last modified date in the header.\nIf there are no changes, then there is no need to return the resource, as the client already has the most recent version.\n\nImplementing 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`.\nIn 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.\nThis 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.\n\n### Optimistic Concurrency\n\nOptimistic 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.\nClients 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.\nFor example, the client can specify an `If-Match` header with the last ETag value received by the client in an update request.\nThe service processes the update only if the ETag value in the header matches the ETag of the current resource on the server.\nBy computing and returning ETags for your resources, you enable clients to avoid using a strategy where the \"last write always wins.\"\n\n## Returning String Offsets & Lengths (Substrings)\n\nSome 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.\nWhen 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:\n\n| Encoding    | Example languages |\n| -------- | ------- |\n| UTF-8 | Go, Rust, Ruby, PHP |\n| UTF-16 | JavaScript, Java, C# |\n| CodePoint (UTF-32) | Python |\n\nBecause 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.\n\nFor example, if a service response needed to identify offset & length values for \"name\" and \"email\" substrings, the JSON response would look like this:\n\n```text\n{\n  (... other properties not shown...)\n  \"fullString\": \"(...some string containing a name and an email address...)\",\n  \"name\": {\n    \"offset\": {\n      \"utf8\": 12,\n      \"utf16\": 10,\n      \"codePoint\": 4\n    },\n    \"length\": {\n      \"uft8\": 10,\n      \"utf16\": 8,\n      \"codePoint\": 2\n    }\n  },\n  \"email\": {\n    \"offset\": {\n      \"utf8\": 12,\n      \"utf16\": 10,\n      \"codePoint\": 4\n    },\n    \"length\": {\n      \"uft8\": 10,\n      \"utf16\": 8,\n      \"codePoint\": 4\n    }\n  }\n}\n```\n\nThen, the Go developer, for example, would get the substring containing the name using code like this:\n\n```go\n   var response := client.SomeMethodReturningJSONShownAbove(...)\n   name := response.fullString[ response.name.offset.utf8 : response.name.offset.utf8 + response.name.length.utf8]\n```\n\nThe 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.\n\n## Getting Help: The Azure REST API Stewardship Board\nThe 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.\n\n### Typical Review Session\nWhen engaging with the API REST Stewardship board, your working sessions will generally focus on three areas:\n- 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.\n- Consistency - Your services should look and behave as though they are natural part of the Azure platform.\n- Well formed - Do your services adhere to REST and Azure standards, e.g. proper return codes, use of headers.\n- 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.\n\nIt 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.\nWith 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.\n"
  },
  {
    "path": "azure/Guidelines.md",
    "content": "# Microsoft Azure REST API Guidelines\n\n<!-- cspell:ignore autorest, BYOS, etag, idempotency, maxpagesize, innererror, trippable, nextlink, condreq, etags -->\n<!-- markdownlint-disable MD033 MD049 MD055 -->\n\n<!--\nNote to contributors: All guidelines now have an anchor tag to allow cross-referencing from associated tooling.\nThe anchor tags within a section using a common prefix to ensure uniqueness with anchor tags in other sections.\nPlease ensure that you add an anchor tag to any new guidelines that you add and maintain the naming convention.\n-->\n\n## History\n\n<details>\n  <summary>Expand change history</summary>\n\n| Date        | Notes                                                          |\n| ----------- | -------------------------------------------------------------- |\n| 2025-Mar-28 | Added guidelines about JSON ID and null values                 |\n| 2024-Mar-17 | Updated LRO guidelines                                         |\n| 2024-Jan-17 | Added guidelines on returning string offsets & lengths         |\n| 2023-May-12 | Explain service response for missing/unsupported `api-version` |\n| 2023-Apr-21 | Update/clarify guidelines on POST method repeatability         |\n| 2023-Apr-07 | Update/clarify guidelines on polymorphism                      |\n| 2022-Sep-07 | Updated URL guidelines for DNS Done Right                      |\n| 2022-Jul-15 | Update guidance on long-running operations                     |\n| 2022-May-11 | Drop guidance on version discovery                             |\n| 2022-Mar-29 | Add guidelines about using durations                           |\n| 2022-Mar-25 | Update guideline for date values in headers to follow RFC 7231 |\n| 2022-Feb-01 | Updated error guidance                                         |\n| 2021-Sep-11 | Add long-running operations guidance                           |\n| 2021-Aug-06 | Updated Azure REST Guidelines per Azure API Stewardship Board. |\n| 2020-Jul-31 | Added service advice for initial versions                      |\n| 2020-Mar-31 | 1st public release of the Azure REST API Guidelines            |\n\n</details>\n\n## Introduction\n\nThese 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:\n- Developer friendly via consistent patterns & web standards (HTTP, REST, JSON)\n- Efficient & cost-effective\n- Work well with SDKs in many programming languages\n- Customers can create fault-tolerant apps by supporting retries/idempotency/optimistic concurrency\n- Sustainable & versionable via clear API contracts with 2 requirements:\n  1. Customer workloads must never break due to a service change\n  2. Customers can adopt a version without requiring code changes\n\nTechnology 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.*\n\n*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).*\n\n### Prescriptive Guidance\nThis document offers prescriptive guidance labeled as follows:\n\n:white_check_mark: **DO** adopt this pattern. If you feel you need an exception, contact the Azure HTTP/REST Stewardship Board **prior** to implementation.\n\n: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.\n\n:heavy_check_mark: **YOU MAY** consider this pattern if appropriate to your situation. No notification to the Azure HTTP/REST Stewardship Board is required.\n\n: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.\n\n:no_entry: **DO NOT** adopt this pattern. If you feel you need an exception, contact the Azure HTTP/REST Stewardship Board **prior** to implementation.\n\n*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.*\n\n## Building Blocks: HTTP, REST, & JSON\nThe 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.\n\n<a href=\"#http\" name=\"http\"></a>\n### HTTP\nAzure 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:\n\n- [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)\n- [HTTP Request / Response Pattern](#http-request--response-pattern)\n- [HTTP Query Parameters and Header Values](#http-query-parameters-and-header-values)\n\n#### Uniform Resource Locators (URLs)\n\nA 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.\n\n<a href=\"#http-url-pattern\" name=\"http-url-pattern\">:white_check_mark:</a> **DO** use this URL pattern:\n```text\nhttps://<tenant>.<region>.<service>.<cloud>/<service-root>/<resource-collection>/<resource-id>\n```\n\nWhere:\n | Field | Description\n | - | - |\n | tenant | Regionally-unique ID representing a tenant (used for isolation, billing, quota enforcement, lifetime of resources, etc.)\n | 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\"\n | service | Name of the service (ex: blobstore, servicebus, directory, or management)\n | cloud | Cloud domain name, e.g. `azure.net` (see Azure CLI's \"az cloud list\")\n | service&#x2011;root | Service-specific path (ex: blobcontainer, myqueue)\n | resource&#x2011;collection | Name of the collection, unabbreviated, pluralized\n | 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.\n\n<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.\n\n<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\n\n<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.\n\nSome 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'\n\n<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\n\n<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.\n\n<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 `:`).\n\n<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)\n\n<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)]: `/  ?  #  [  ]  @  !  $  &  '  (  )  *  +  ,  ;  =`\n\n<a href=\"#http-direct-endpoints\" name=\"http-direct-endpoints\">:heavy_check_mark:</a> **YOU MAY** support a direct endpoint URL for performance/routing:\n```text\nhttps://<tenant>-<service-root>.<service>.<cloud>/...\n```\n\nExamples:\n- Request URL: `https://blobstore.azure.net/contoso.com/account1/container1/blob2`\n- 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`\n- GUID format: `https://00000000-0000-0000-C000-000000000046-account1.blobstore.azure.net/container1/blob2`\n\n<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.\n\n<a href=\"#http-url-parameter-values\" name=\"http-url-parameter-values\">:heavy_check_mark:</a> **YOU MAY** use URLs as values\n```text\nhttps://api.contoso.com/items?url=https://resources.contoso.com/shoes/fancy\n```\n\n#### HTTP Request / Response Pattern\nThe 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.\n\nCloud 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.\n\n##### Exactly Once Behavior = Client Retries & Service Idempotency\n\n<a href=\"#http-all-methods-idempotent\" name=\"http-all-methods-idempotent\">:white_check_mark:</a> **DO** ensure that _all_ HTTP methods are idempotent.\n\n<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.\n\n<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)).\n\n##### HTTP Return Codes\n\n<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:\n\nMethod | Description | Response Status Code\n-------|-------------|---------------------\nPATCH  | Create/Modify the resource with JSON Merge Patch | `200-OK`, `201-Created`\nPUT    | Create/Replace the _whole_ resource | `200-OK`, `201-Created`\nPOST   | Create new resource (ID set by service) | `201-Created` with URL of created resource\nPOST   | Action | `200-OK`\nGET    | Read (i.e. list) a resource collection | `200-OK`\nGET    | Read the resource | `200-OK`\nDELETE | Remove the resource | `204-No Content`\\; avoid `404-Not Found`\n\n<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.\n\n<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\n\n<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`.\n\n<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`)\n\n<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.\n\n<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.]\n\n<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\n\n#### HTTP Query Parameters and Header Values\n\n<a href=\"#http-query-names-casing\" name=\"http-query-names-casing\">:white_check_mark:</a> **DO** use camel case for query parameter names.\n\nNote: Certain legacy query parameter names use kebab-casing and are allowed only for backwards compatibility.\n\nBecause 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.\n\n<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.\n\n<a href=\"#http-parameter-serialization\" name=\"http-parameter-serialization\">:white_check_mark:</a> **DO** use the following table when translating strings:\n\nData type | Document that string must be\n--------- | -------\nBoolean   | true / false (all lowercase)\nInteger   | -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))\nFloat     | [IEEE-754 binary64](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)\nString    | (Un)quoted?, max length, legal characters, case-sensitive, multiple delimiter\nUUID      | 123e4567-e89b-12d3-a456-426614174000 (no {}s, hyphens, case-insensitive) [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)\nDate/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)\nDate/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)\nByte array | Base-64 encoded, max length\nArray      | One of a) a comma-separated list of values (preferred), or b) separate `name=value` parameter instances for each value of the array\n\n\nThe table below lists the headers most used by Azure services:\n\nHeader Key          | Applies to | Example\n------------------- | ---------- | -------------\n_authorization_     | Request    | Bearer eyJ0...Xd6j (Support Azure Active Directory)\n_x-ms-useragent_    | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))\ntraceparent         | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))\ntracecontext        | Request    | (see [Distributed Tracing & Telemetry](#distributed-tracing--telemetry))\naccept              | Request    | application/json\nIf-Match            | Request    | \"67ab43\" or * (no quotes) (see [Conditional Requests](#conditional-requests))\nIf-None-Match       | Request    | \"67ab43\" or * (no quotes) (see [Conditional Requests](#conditional-requests))\nIf-Modified-Since   | Request    | Sun, 06 Nov 1994 08:49:37 GMT (see [Conditional Requests](#conditional-requests))\nIf-Unmodified-Since | Request    | Sun, 06 Nov 1994 08:49:37 GMT (see [Conditional Requests](#conditional-requests))\ndate                | 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))\n_content-type_      | Both       | application/merge-patch+json\n_content-length_    | Both       | 1024\n_x-ms-request-id_   | Response   | 4227cdc5-9f48-4e84-921a-10967cb785a0\nETag                | Response   | \"67ab43\" (see [Conditional Requests](#conditional-requests))\nlast-modified       | Response   | Sun, 06 Nov 1994 08:49:37 GMT\n_x-ms-error-code_   | Response   | (see [Handling Errors](#handling-errors))\n_azure-deprecating_ | Response   | (see [Deprecating Behavior Notification](#deprecating-behavior-notification))\nretry-after         | Response   | 180 (see [RFC 7231, Section 7.1.3](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3))\n\n<a href=\"#http-header-support-standard-headers\" name=\"http-header-support-standard-headers\">:white_check_mark:</a> **DO** support all headers shown in _italics_\n\n<a href=\"#http-header-names-casing\" name=\"http-header-names-casing\">:white_check_mark:</a> **DO** specify headers using kebab-casing\n\n<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\n\n<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\n\n<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\".\n\nNote: 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.\n\n<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.\n\nYour 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.\n\n<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\n\n<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)].\n\n**Additional References**\n- [StackOverflow - Difference between http parameters and http headers](https://stackoverflow.com/questions/40492782)\n- [Standard HTTP Headers](https://httpwg.org/specs/rfc7231.html#header.field.registration)\n- [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)\n\n<a href=\"#rest\" name=\"rest\"></a>\n### REpresentational State Transfer (REST)\nREST 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.\nThese 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.\nThere 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.\n\nWhen designing your service, it is important to optimize for the developer using your API.\n\n<a href=\"#rest-clear-naming\" name=\"rest-clear-naming\">:white_check_mark:</a> **DO** focus heavily on clear & consistent naming\n\n<a href=\"#rest-paths-make-sense\" name=\"rest-paths-make-sense\">:white_check_mark:</a> **DO** ensure your resource paths make sense\n\n<a href=\"#rest-simplify-operations\" name=\"rest-simplify-operations\">:white_check_mark:</a> **DO** simplify operations with few required query parameters & JSON fields\n\n<a href=\"#rest-specify-string-value-constraints\" name=\"rest-specify-string-value-constraints\">:white_check_mark:</a> **DO** establish clear contracts for string values\n\n<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\n\n#### Resource Schema & Field Mutability\n\n<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.\n\n<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:\n\nField Mutability | Service Request's behavior for this field\n-----------------| -----------------------------------------\n**Create** | Service honors field only when creating a resource. Minimize create-only fields so customers don't have to delete & re-create the resource.\n**Update** | Service honors field when creating or updating a resource\n**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\n\nIn 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.\nBecause 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.\n\n<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.\n\n<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\n\n<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.\n\n<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).\n\n<a href=\"#rest-delete-resource\" name=\"rest-delete-resource\">:white_check_mark:</a> **DO** use DELETE to remove a resource.\n\n<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.\n\n<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**.\n\n<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.\n\n<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.\n\n##### Create / Update / Replace Processing Rules\n\n<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:\n\nWhen using this method | if this condition happens | use&nbsp;this&nbsp;response&nbsp;code\n---------------------- | ------------------------- | ----------------------\nPATCH/PUT | Any JSON field name/value not known/valid to the api-version | `400-Bad Request`\nPATCH/PUT | Any Read field passed (client can't set Read fields) | `400-Bad Request`\n| **If&nbsp;the&nbsp;resource&nbsp;does&nbsp;not&nbsp;exist** |\nPATCH/PUT | Any mandatory Create/Update field missing | `400-Bad Request`\nPATCH/PUT | Create resource using Create/Update fields | `201-Created`\n| **If&nbsp;the&nbsp;resource&nbsp;already&nbsp;exists** |\nPATCH | Any Create field doesn't match current value (allows retries) | `409-Conflict`\nPATCH | Update resource using Update fields | `200-OK`\nPUT | Any mandatory Create/Update field missing | `400-Bad Request`\nPUT | Overwrite resource entirely using Create/Update fields | `200-OK`\n\n#### Handling Errors\nThere are 2 kinds of errors:\n- An error where you expect customer code to gracefully recover at runtime\n- An error indicating a bug in customer code that is unlikely to be recoverable at runtime; the customer must just fix their code\n\n<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.\n\n*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.*\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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:\n\n**ErrorResponse** : Object\n\nProperty | Type | Required | Description\n-------- | ---- | :------: | -----------\n`error` | ErrorDetail | ✔ | The top-level error object whose `code` matches the `x-ms-error-code` response header\n\n**ErrorDetail** : Object\n\nProperty | Type | Required | Description\n-------- | ---- | :------: | -----------\n`code` | String | ✔ | One of a server-defined set of error codes.\n`message` | String | ✔ | A human-readable representation of the error.\n`target` | String |  | The target of the error.\n`details` | ErrorDetail[] |  | An array of details about specific errors that led to this reported error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n_additional properties_ |   | | Additional properties that can be useful when debugging.\n\n**InnerError** : Object\n\nProperty | Type | Required | Description\n-------- | ---- | :------: | -----------\n`code` | String |  | A more specific error code than was provided by the containing error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n\nExample:\n```json\n{\n  \"error\": {\n    \"code\": \"InvalidPasswordFormat\",\n    \"message\": \"Human-readable description\",\n    \"target\": \"target of error\",\n    \"innererror\": {\n      \"code\": \"PasswordTooShort\",\n      \"minLength\": 6,\n    }\n  }\n}\n```\n\n<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.\n\n<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.\n\n<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.\n\n*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).*\n\n<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).\n\n<a href=\"#json\" name=\"json\"></a>\n### JSON\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\nServices, 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:\n\n Type | Description\n ---- | -----------\n Boolean | true/false (always lowercase)\n Number  | Signed floating point (IEEE-754 binary64; int range: -2<sup>53</sup>+1 to +2<sup>53</sup>-1)\n String  | Used for everything else\n\n<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. \n\n<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).\n\n<a href=\"#json-integer-values\" name=\"json-integer-values\">:white_check_mark:</a> **DO** use integers within the acceptable range of JSON number.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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`.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### Enums & SDKs (Client libraries)\nIt 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.\n\nHowever, 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.\nThis 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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### Polymorphic types\n\nPolymorphism 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.\n\nNote: 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.\n\n<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.\n\nBelow is an example of JSON for a Rectangle and Circle with a discriminator field named `kind`:\n\n**Rectangle**\n```json\n{\n   \"kind\": \"rectangle\",\n   \"x\": 100,\n   \"y\": 50,\n   \"width\": 10,\n   \"length\": 24,\n   \"fillColor\": \"Red\",\n   \"lineColor\": \"White\",\n   \"subscription\": {\n      \"kind\": \"free\"\n   }\n}\n```\n\n**Circle**\n```json\n{\n   \"kind\": \"circle\",\n   \"x\": 100,\n   \"y\": 50,\n   \"radius\": 10,\n   \"fillColor\": \"Green\",\n   \"lineColor\": \"Black\",\n   \"subscription\": {\n      \"kind\": \"paid\",\n      \"expiration\": \"2024\",\n      \"invoice\": \"123456\"\n   }\n}\n```\nBoth 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.\n\nThe [Azure Naming Guidelines](./ConsiderationsForServiceDesign.md#common-names) recommend that the discriminator field be named `kind`.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\nUpdating an array property with JSON merge-patch is not version-resilient if the array contains polymorphic types.\n\n## Common API Patterns\n\n<a href=\"#actions\" name=\"actions\"></a>\n### Performing an Action\nThe 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.\n\n<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\n**URL Pattern**\n```text\nhttps://.../<resource-collection>/<resource-id>:<action>?<input parameters>\n```\n\n**Example**\n```text\nhttps://.../users/Bob:grant?access=read\n```\n\n<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\n**URL Pattern**\n```text\nhttps://.../<resource-collection>:<action>?<input parameters>\n```\n\n**Example**\n```text\nhttps://.../users:grant?access=read\n```\n\nNote: To avoid potential collision of actions and resource ids, you should disallow the use of the \":\" character in resource ids.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<a href=\"#collections\" name=\"collections\"></a>\n### Collections\n<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.\n\n<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.\n\nNOTE: It is a breaking change to add paging in the future\n\n<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).\n\n**Example Response Body**\n```json\n{\n    \"value\": [\n       { \"id\": \"Item 01\", \"etag\": \"\\\"abc\\\"\", \"price\": 99.95, \"size\": \"Medium\" },\n       { … },\n       { … },\n       { \"id\": \"Item 99\", \"etag\": \"\\\"def\\\"\", \"price\": 59.99, \"size\": \"Large\" }\n    ],\n    \"nextLink\": \"{opaqueUrl}\"\n }\n```\n\n<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\\\"\".\n\n<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).\n\n<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.\n\nNote: The service is responsible for performing any URL-encoding required on the `nextLink` URL.\n\n<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`.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### Query options\n\n<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:\n\nParameter&nbsp;name | Type | Description\n------------------- | ---- | -----------\n`filter`       | string            | an expression on the resource type that selects the resources to be returned\n`orderby`      | string&nbsp;array | a list of expressions that specify the order of the returned resources\n`skip`         | integer           | an offset into the collection of the first resource to be returned\n`top`          | integer           | the maximum number of resources to return from the collection\n`maxpagesize`  | integer           | the maximum number of resources to include in a single response\n`select`       | string&nbsp;array | a list of field names to be returned for each resource\n`expand`       | string&nbsp;array | a list of the related resources to be included in line with each resource\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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)).\n\n#### filter\n\n<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.\n\nThe 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.\n\n<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.\n\nExample: return all Products whose Price is less than $10.00\n\n```text\nGET https://api.contoso.com/products?filter=price lt 10.00\n```\n\n##### filter operators\n\n:heavy_check_mark: **YOU MAY** support the following operators in filter expressions:\n\nOperator                 | Description           | Example\n--------------------     | --------------------- | -----------------------------------------------------\n**Comparison Operators** |                       |\neq                       | Equal                 | city eq 'Redmond'\nne                       | Not equal             | city ne 'London'\ngt                       | Greater than          | price gt 20\nge                       | Greater than or equal | price ge 10\nlt                       | Less than             | price lt 20\nle                       | Less than or equal    | price le 100\n**Logical Operators**    |                       |\nand                      | Logical and           | price le 200 and price gt 3.5\nor                       | Logical or            | price le 3.5 or price gt 200\nnot                      | Logical negation      | not price le 3.5\n**Grouping Operators**   |                       |\n( )                      | Precedence grouping   | (priority eq 1 or city eq 'Redmond') and price gt 100\n\n<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.\n\n<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:\n\n| Group           | Operator | Description\n| ----------------|----------|------------\n| Grouping        | ( )      | Precedence grouping   |\n| Unary           | not      | Logical Negation      |\n| Relational      | gt       | Greater Than          |\n|                 | ge       | Greater than or Equal |\n|                 | lt       | Less Than             |\n|                 | le       | Less than or Equal    |\n| Equality        | eq       | Equal                 |\n|                 | ne       | Not Equal             |\n| Conditional AND | and      | Logical And           |\n| Conditional OR  | or       | Logical Or            |\n\n<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).\n\n##### Operator examples\nThe following examples illustrate the use and semantics of each of the logical operators.\n\nExample: all products with a name equal to 'Milk'\n\n```text\nGET https://api.contoso.com/products?filter=name eq 'Milk'\n```\n\nExample: all products with a name not equal to 'Milk'\n\n```text\nGET https://api.contoso.com/products?filter=name ne 'Milk'\n```\n\nExample: all products with the name 'Milk' that also have a price less than 2.55:\n\n```text\nGET https://api.contoso.com/products?filter=name eq 'Milk' and price lt 2.55\n```\n\nExample: all products that either have the name 'Milk' or have a price less than 2.55:\n\n```text\nGET https://api.contoso.com/products?filter=name eq 'Milk' or price lt 2.55\n```\n\nExample: all products that have the name 'Milk' or 'Eggs' and have a price less than 2.55:\n\n```text\nGET https://api.contoso.com/products?filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55\n```\n\n#### orderby\n\n<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.\n*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.*\n\nThe value of the `orderby` parameter is a comma-separated list of expressions used to sort the items.\nA special case of such an expression is a property path terminating on a primitive property.\n\nEach 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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\nFor example, to return all people sorted by name in ascending order:\n```text\nGET https://api.contoso.com/people?orderby=name\n```\n\nFor example, to return all people sorted by name in descending order and a secondary sort order of hireDate in ascending order.\n```text\nGET https://api.contoso.com/people?orderby=name desc,hireDate\n```\n\nSorting MUST compose with filtering such that:\n```text\nGET https://api.contoso.com/people?filter=name eq 'david'&orderby=hireDate\n```\nwill return all people whose name is David sorted in ascending order by hireDate.\n\n##### Considerations for sorting with pagination\n\n<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.\n\n##### skip\n<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.\n\n<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.\n##### top\n\n<a href=\"#collections-\" name=\"collections-\"></a>\n<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.\n\nIf supporting `top`:\n: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.\n\n<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`.\n\n##### maxpagesize\n\n<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.\n\n<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.\n\n<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.\n\n<a href=\"#versioning\" name=\"versioning\"></a>\n### API Versioning\n\nAzure services need to change over time. However, when changing a service, there are 2 requirements:\n 1. Already-running customer workloads must not break due to a service change\n 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.)\n\n*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.*\n\n<a href=\"#versioning-review-required\" name=\"versioning-review-required\">:white_check_mark:</a> **DO** review any API changes with the Azure API Stewardship Board\n\nClients 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.\n\n<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.\n\n<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`.\n\n<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.\n\n<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).\n\n```text\nPUT https://service.azure.com/users/Jeff?api-version=2021-06-04\n```\n\n<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\n\nWhen 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\n\n<a href=\"#versioning-no-breaking-changes\" name=\"versioning-no-breaking-changes\">:no_entry:</a> **DO NOT** introduce any breaking changes into the service.\n\n<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.\n\n<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\n\n<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.\n\n#### Use Extensible Enums\n\nWhile 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:\n\n```json\n\"createdByType\": {\n   \"type\": \"string\",\n   \"description\": \"The type of identity that created the resource.\",\n   \"enum\": [\n      \"User\",\n      \"Application\",\n      \"ManagedIdentity\",\n      \"Key\"\n   ],\n   \"x-ms-enum\": {\n      \"name\": \"createdByType\",\n      \"modelAsString\": true\n   }\n}\n```\n\n<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.\n\n<a href=\"#deprecation\" name=\"deprecation\"></a>\n### Deprecating Behavior Notification\n\nWhen 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.\n\nThe 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.\n\n<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.\n> NOTE: We do not want to scare customers with this header.\n\n<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.\n\nDeprecations should use the following pattern:\n```text\n<description> will retire on <date> (<url>)\n```\n\nMultiple deprecations are allowed, semicolon delimited.\n\nWhere the following placeholders should be provided:\n- `description`: a human-readable description of what is being deprecated\n- `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\".\n- `url`: a fully qualified url that the user can follow to learn more about what is being deprecated, preferably to Azure Updates.\n\nFor example:\n- `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/)`\n- `azure-deprecating: Model version 2021-01-15 used in Sentiment analysis will retire on 2022-12-01 (https://aka.ms/ta-modelversions?sentimentAnalysis)`\n- `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/)`\n\n<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/).\n\n<a href=\"#repeatability\" name=\"repeatability\"></a>\n### Repeatability of requests\n\nFault 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](\nhttps://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#performing-an-action).\n\n<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.\n- The tracked time window (difference between the `Repeatability-First-Sent` value and the current time) **MUST** be at least 5 minutes.\n- Document the POST operation's support for the `Repeatability-First-Sent`, `Repeatability-Request-ID`, and `Repeatability-Result` headers in the API contract and documentation.\n- Any operation that does not support repeatability headers should return a 501 (Not Implemented) response for any request that contains valid repeatability request headers.\n\n### Long-Running Operations & Jobs\n\nA _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.\n\nLROs 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.\n\n<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.\n\n<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) .\n\n#### Patterns to Initiate a Long-Running Operation\n\n<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.\n\n<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.\n\n<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.\n\n<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).\n\n#### Create or replace operation with additional long-running processing\n<a href=\"#put-operation-with-additional-long-running-processing\" name=\"put-operation-with-additional-long-running-processing\"></a>\n\n<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:\n\n```text\nPUT /UrlToResourceBeingCreated?api-version=<api-version>\noperation-id: <optionalStatusMonitorResourceId>\n\n<JSON Resource in body>\n```\n\nThe response must look like this:\n\n```text\n201 Created\noperation-id: <statusMonitorResourceId>\noperation-location: https://operations/<operation-id>?api-version=<api-version>\n\n<JSON Resource in body>\n```\n\nThe request and response body schemas must be identical and represent the resource.\n\nThe PUT creates or replaces the resource immediately and returns but the additional long-running processing can take time to complete.\n\nFor 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.\n\nFor 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.\n\n<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.\n\nIf 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.\n\n<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.\n\n<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).\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### DELETE LRO pattern\n\n<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:\n\n```text\nDELETE /UrlToResourceBeingDeleted?api-version=<api-version>\noperation-id: <optionalStatusMonitorResourceId>\n```\n\nThe response must look like this:\n\n```text\n202 Accepted\noperation-id: <statusMonitorResourceId>\noperation-location: https://operations/<operation-id>\n```\n\nConsistent with non-LRO DELETE operations, if a request body is specified, return `400-Bad Request`.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### LRO action on a resource pattern\n<a href=\"#post-or-delete-lro-pattern\" name=\"post-or-delete-lro-pattern\"></a><!-- Preserve old header link -->\n\n<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:\n\n```text\nPOST /UrlToExistingResource:<action>?api-version=<api-version>&<actionParamsGoHere>\noperation-id: <optionalStatusMonitorResourceId>`\n\n<JSON Action parameters can go in body if query params don't work>\n```\n\nThe response must look like this:\n\n```text\n202 Accepted\noperation-id: <statusMonitorResourceId>\noperation-location: https://operations/<operation-id>\n\n<JSON Status Monitor Resource in body>\n```\n\nThe request body contains information to be used to execute the action.\n\nFor 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.\n\nFor 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.\n\n<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.\n\n<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.\n\n<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.\n\n<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).\n\n<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.\n\n<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.\n\n<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).\n\n#### LRO action with no related resource pattern\n\n<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):\n\n```text\nPUT <operation-endpoint>/<operation-id>?api-version=<api-version>\n\n<JSON body with parameters for the operation>>\n```\n\nThe response must look like this:\n\n```text\n201 Created\noperation-location: <absolute URL of status monitor>\n\n<JSON Status Monitor Resource in body>\n```\n\n<a href=\"#lro-put-action-operation-endpoint\" name=\"lro-put-action-operation-endpoint\">:ballot_box_with_check:</a> **YOU SHOULD**\ndefine a unique operation endpoint for each LRO action with no related resource.\n\n<a href=\"#lro-put-action-operation-id\" name=\"lro-put-action-operation-id-in-path\">:white_check_mark:</a> **DO** require the\n`Operation-Id` as the final path segment in the URL.\n\nNote: The `operation-id` URL segment (not header) is *required*, forcing the client to specify the status monitor's resource ID\nand is also used for retries/idempotency.\n\n<a href=\"#lro-put-action-returns-201\" name=\"lro-put-action-returns-201\">:white_check_mark:</a> **DO** return a `201 Created` status code\nwith an `operation-location` response header if the LRO Action operation was accepted for processing.\n\n<a href=\"#lro-put-action-returns-status-monitor\" name=\"lro-put-action-returns-status-monitor\">:white_check_mark:</a> **DO** return a\nstatus monitor in the response body that contains the operation status, request parameters, and when the operation completes either\nthe operation result or error.\n\nNote: Since all request parameters must be present in the status monitor,\nthe request and response body of the PUT can be defined with a single schema.\n\n<a href=\"#lro-put-action-status-monitor-url\" name=\"lro-put-action-status-monitor-url\">:ballot_box_with_check:</a> **YOU SHOULD**\nreturn the status monitor for an operation for a subsequent GET on the URL that initiates the LRO, and use this endpoint as\nthe status monitor URL returned in the `operation-location` response header.\n\n#### The Status Monitor Resource\n\nAll 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.\n\n<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:\n\nProperty | Type        | Required | Description\n-------- | ----------- | :------: | -----------\n`id`     | string      | true     | The unique id of the operation\n`kind`   | string enum | true(*)  | The kind of operation\n`status` | string enum | true     | The operation's current status: \"NotStarted\", \"Running\", \"Succeeded\", \"Failed\", and \"Canceled\"\n`error`  | ErrorDetail |          | If `status`==\"Failed\", contains reason for failure\n`result` | object      |          | If `status`==\"Succeeded\" && Action LRO (POST or PUT), contains success result if needed\nadditional<br/>properties | | | Additional named or dynamic properties of the operation\n\n(*): When a status monitor endpoint supports multiple operations with different result structures or additional properties,\nthe status monitor **must** be polymorphic -- it **must** contain a required `kind` property that indicates the kind of long-running operation.\n\n#### Obtaining status and results of long-running operations\n\n<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:\n\n```text\nGET <operation-endpoint>/<operation-id>?api-version=<api-version>\n```\n\nThe response must look like this:\n\n```text\n200 OK\nretry-after: <delay-seconds>    (if status not terminal)\n\n<JSON Status Monitor Resource in body>\n```\n\n<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.\n\n<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.\n\n- 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.\n\n<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).\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n#### Pattern to List Status Monitors\n\nUse the following patterns to allow clients to list Status Monitor resources.\n\n<a href=\"#lro-list-status-monitors\" name=\"lro-list-status-monitors\">:ballot_box_with_check:</a>\n**YOU MAY** support a GET method on any status monitor collection URL that returns a list of the status monitors in that collection.\n\n<a href=\"#lro-put-action-list-status-monitors\" name=\"lro-put-action-list-status-monitors\">:ballot_box_with_check:</a>\n**YOU SHOULD** support a list operation for any status monitor collection that includes status monitors for LRO Actions with no related resource.\n\n<a href=\"#lro-list-status-monitors-filter\" name=\"lro-list-status-monitors-filter\">:ballot_box_with_check:</a>\n**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.\n\nFor example, the following request should return all status monitor resources whose `kind` is either \"VMInitializing\" *or* \"VMRebooting\"\nand whose status is \"NotStarted\" *or* \"Succeeded\".\n\n```text\nGET /operations?filter=(kind eq 'VMInitializing' or kind eq 'VMRebooting') and (status eq 'NotStarted' or status eq 'Succeeded')\n```\n\n<a href=\"#byos\" name=\"byos\"></a>\n### Bring your own Storage (BYOS)\n\nMany services need to store and retrieve data files. For this scenario, the service should not implement its own\nstorage APIs and should instead leverage the existing Azure Storage service. When doing this, the customer\n\"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.\n\nWhile 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.\n\n<a href=\"#byos-pattern\" name=\"byos-pattern\">:white_check_mark:</a> **DO** use the Bring Your Own Storage pattern.\n\n<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`).\n\n<a href=\"#byos-allow-container-reuse\" name=\"byos-allow-container-reuse\">:no_entry:</a> **DO NOT** require a fresh container per operation.\n\n<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.\n\n<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.\n\n<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.\n\n\n#### Handling 'downstream' errors\nIt 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.\n\n<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.\n\n#### Working with files\nGenerally speaking, there are two patterns that you will encounter when working with files; single file access, and file collections.\n\n##### Single file access\nDesigning an API for accessing a single file, depending on your scenario, is relatively straight forward.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\nWhen 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).\n\n<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)\n\n<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.\n\nA 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.\n\nFor example, a service's request body to configure BYOS may look like this:\n\n```json\n{\n  \"input\":{\n    \"location\": \"https://mycompany.blob.core.windows.net/documents/english/?<sas token>\",\n    \"delimiter\": \"/\",\n    \"extensions\" : [ \".bmp\", \".jpg\", \".tif\", \".png\" ],\n    \"lastModified\": \"Wed, 21 Oct 2015 07:28:00 GMT\"\n  },\n  \"output\":{\n    \"location\": \"https://mycompany.blob.core.windows.net/documents/spanish/?<sas token>\",\n    \"delimiter\":\"/\"\n  }\n}\n```\n\nDepending on the requirements of the service, there can be any number of \"input\" and \"output\" sections, including none.\n\n<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 \"\\\".\n\n<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).\n\n<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.\n\n<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.\n\n<a href=\"#condreq\" name=\"condreq\"></a>\n### Conditional Requests\n\nThe [HTTP Standard][] defines request headers that clients may use to specify a _precondition_\nfor execution of an operation. These headers allow clients to implement efficient caching mechanisms\nand 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`.\n\n[HTTP Standard]: https://datatracker.ietf.org/doc/html/rfc9110\n\n<!-- condreq-support-etags-consistently has been subsumed by condreq-support but we retain the anchor to avoid broken links -->\n<a href=\"#condreq-support-etags-consistently\" name=\"condreq-support-etags-consistently\"></a>\n<!-- condreq-for-read has been subsumed by condreq-support but we retain the anchor to avoid broken links -->\n<a href=\"#condreq-for-read\" name=\"condreq-for-read\"></a>\n<!-- condreq-no-pessimistic-update has been subsumed by condreq-support but we retain the anchor to avoid broken links -->\n<a href=\"#condreq-no-pessimistic-update\" name=\"condreq-no-pessimistic-update\"></a>\n<a href=\"#condreq-support\" name=\"condreq-support\">:white_check_mark:</a> **DO** honor any precondition headers received as part of a client request.\n\nThe HTTP Standard does not allow precondition headers to be ignored, as it can be unsafe to do so.\n\n<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.\n\nNote: 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.\n\nWhile conditional requests can be implemented using last modified dates, entity tags (\"ETags\") are strongly\npreferred since last modified dates cannot distinguish updates made less than a second apart.\n\n<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).\n\n#### Conditional Request behavior\n\nThis section gives a summary of the processing to perform for precondition headers.\nSee the [Conditional Requests section of the HTTP Standard][] for details on how and when to evaluate these headers.\n\n[Conditional Requests section of the HTTP Standard]: https://datatracker.ietf.org/doc/html/rfc9110#name-conditional-requests\n\n<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:\n\n| GET Request | Return code | Response                                    |\n|:------------|:------------|:--------------------------------------------|\n| ETag value = `If-None-Match` value   | `304-Not Modified` | no additional information   |\n| ETag value != `If-None-Match` value  | `200-OK`           | Response body include the serialized value of the resource (typically JSON)    |\n\nFor more control over caching, please refer to the `cache-control` [HTTP header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control).\n\n<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:\n\n| Operation   | Header        | Value | ETag check | Return code | Response       |\n|:------------|:--------------|:------|:-----------|:------------|----------------|\n| 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).  |\n| 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.|\n| 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).  |\n| 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.|\n| DELETE      | `If-Match` | value of ETag     | value matches the latest value on the server | `204-No Content` | Response body SHOULD be empty.  |\n| DELETE      | `If-Match` | value of ETag     | value does NOT match the latest value on the server | `412-Preconditioned Failed` | Response body SHOULD be empty.|\n\n#### Computing ETags\n\nThe 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.\n\n<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\n\nWhile 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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<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.\n\n<a href=\"#substrings\" name=\"substrings\"></a>\n### Returning String Offsets & Lengths (Substrings)\n\nAll 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).\nWhen 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.\nSee 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.\n\n[Returning String Offsets & Lengths]: https://github.com/microsoft/api-guidelines/blob/vNext/azure/ConsiderationsForServiceDesign.md#returning-string-offsets--lengths-substrings\n\n<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.\n\n<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:\n\n| Property    | Type    | Required | Description |\n| ----------- | ------- | :------: | ----------- |\n| `utf8`      | integer | true     | The offset or length of the substring in UTF-8 encoding |\n| `utf16`     | integer | true     | The offset or length of the substring in UTF-16 encoding |\n| `codePoint` | integer | true     | The offset or length of the substring in CodePoint encoding |\n\n<a href=\"#telemetry\" name=\"telemetry\"></a>\n### Distributed Tracing & Telemetry\n\nAzure SDK client guidelines specify that client libraries must send telemetry data through the `User-Agent` header, `X-MS-UserAgent` header, and Open Telemetry.\nClient 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.\n\n<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.\n\n<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.\n\n**Additional References**\n- [Azure SDK client guidelines](https://azure.github.io/azure-sdk/general_azurecore.html)\n- [Azure SDK User-Agent header policy](https://azure.github.io/azure-sdk/general_azurecore.html#azurecore-http-telemetry-x-ms-useragent)\n- [Azure SDK Distributed tracing policy](https://azure.github.io/azure-sdk/general_azurecore.html#distributed-tracing-policy)\n- [Open Telemetry](https://opentelemetry.io/)\n\nIn addition to distributed tracing, Azure also uses a set of common correlation headers:\n\n|Name                         |Applies to|Description|\n|-----------------------------|----------|-----------|\n|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.\n|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.\n\n## Final thoughts\nThese 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.\n\nThe 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.\nBecause APIs affect nearly all downstream decisions, you are encouraged to reach out to the Stewardship board early in the development process.\nThese 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).\n"
  },
  {
    "path": "azure/README.md",
    "content": "# Azure REST API Guidance\nWhen 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. \n\nDesigning 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.\n* [Considerations for Service Design](ConsiderationsForServiceDesign.md)\n* [REST API Guidelines](Guidelines.md)\n* [OpenAPI Style Guidelines](https://github.com/Azure/azure-api-style-guide/blob/main/README.md)\n* [Versioning policy for Azure services, SDKs, and CLI tools](https://learn.microsoft.com/en-us/azure/developer/intro/azure-service-sdk-tool-versioning)\n* [Breaking Changes](https://aka.ms/azapi/breakingchanges) <sub>Note: Internal Microsoft link</sub>\n\nYou 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.\n\n<sub>Note: The Teams channel is internal MS.</sup>\n"
  },
  {
    "path": "azure/VersioningGuidelines.md",
    "content": "# Azure Versioning Guidelines\n\n## History\n\n<details>\n  <summary>Expand change history</summary>\n\n| Date        | Notes                                                          |\n| ----------- | -------------------------------------------------------------- |\n| 2024-Nov-14 | Azure Service Versioning & Breaking Change Guidelines       |\n\n</details>\n\n## Guidelines\n\nThis document provides a \"Dos and Don'ts\" list for complying with the Azure Versioning and Breaking Change Policy,\nas documented [internally](aka.ms/AzBreakingChangesPolicy) and [externally](https://learn.microsoft.com/azure/developer/intro/azure-service-sdk-tool-versioning).\n\n:white_check_mark: **DO** thoroughly ensure/test the API contract is entirely correct before merging it into a production branch of the specs repo.\n\nTesting helps avoid \"BugFix\" changes to the API definition. Testing should be done at the HTTP level as well as through generated SDKs.\n\n:white_check_mark: **DO** retire all prior preview API versions 90 days after a new GA or preview API version is released.\n\n:white_check_mark: **DO** contact the Azure Breaking Change Review board to coordinate communications to customers\nwhen releasing an API version requiring the retirement of a prior version.\n\n:white_check_mark: **DO** create a new preview API version for any features that should remain in preview following a new GA release.\n\n:white_check_mark: **DO** use a date strictly later than the most recent GA API version when releasing\na new preview API version.\n\n:white_check_mark: **DO** deprovision any API version that has been retired. Retired APIs versions should behave like\nan unknown API version (see [ref](https://aka.ms/azapi/guidelines#versioning-api-version-unsupported)).\n\n:white_check_mark: **DO** remove retired API versions from the azure-rest-api-specs repo.\n\n: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.\n\nSome examples of behavior changes that must be reviewed are:\n- Introducing or changing rate limits to be more restrictive than previously\n- Changing the permissions required to successfully execute an operation\n\n:no_entry: **DO NOT** change the behavior of an API version that is available to customers either in public preview or GA.\nChanges in behavior should always be introduced in a new API version, with prior versions working as before.\n\n:no_entry: **DO NOT** introduce breaking changes from a prior GA version just to satisfy ARM or Azure API guidelines.\n\nAvoiding breaking changes in a GA API takes precedence over adherence to API guidelines and resolving linter errors.\n\n: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.\n"
  },
  {
    "path": "graph/Guidelines-deprecated.md",
    "content": "\n> # DEPRECATION NOTICE TO READERS\n>\n> 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.\n>\n> ## **Guidance for Microsoft Graph service teams**\n>\n> 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.\n>\n---\n# Microsoft REST API Guidelines\n\nThis are Microsoft's internal company-wide REST API design guidelines.\nTeams at Microsoft typically reference this document when setting API design policy.\nThey may additionally create documents specific to their team, adding further guidance or making adjustments as appropriate to their circumstances.\n\n## Microsoft REST API Guidelines Working Group\n\nName | Name | Name |\n---------------------------- | -------------------------------------- | ----------------------------------------\nDave Campbell (CTO C+E)      | Rick Rashid (CTO ASG)                  | John Shewchuk (Technical Fellow, TED HQ)\nMark Russinovich (CTO Azure) | Steve Lucco (Technical Fellow, DevDiv) | Murali Krishnaprasad (Azure App Plat)\nRob Howard (ASG)             | Peter Torr  (OSG)                      | Chris Mullins (ASG)\n\n<div style=\"font-size:150%\">\nDocument editors: John Gossman (C+E), Chris Mullins (ASG), Gareth Jones (ASG), Rob Dolin (C+E), Mark Stafford (C+E)<br/>\n</div>\n\n# Microsoft REST API Guidelines\n\n## 1. Abstract\nThe Microsoft REST API Guidelines, as a design principle, encourages application developers to have resources accessible to them via a RESTful HTTP interface.\nTo 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.\n\nThis document establishes the guidelines Microsoft REST APIs SHOULD follow so RESTful interfaces are developed consistently.\n\n## 2. Table of contents\n<!-- TOC depthFrom:2 depthTo:4 orderedList:false updateOnSave:false withLinks:true -->\n\n- [Microsoft REST API Guidelines](#microsoft-rest-api-guidelines)\n  - [Microsoft REST API Guidelines Working Group](#microsoft-rest-api-guidelines-working-group)\n- [Microsoft REST API Guidelines](#microsoft-rest-api-guidelines-1)\n  - [1. Abstract](#1-abstract)\n  - [2. Table of contents](#2-table-of-contents)\n  - [3. Introduction](#3-introduction)\n    - [3.1. Recommended reading](#31-recommended-reading)\n  - [4. Interpreting the guidelines](#4-interpreting-the-guidelines)\n    - [4.1. Application of the guidelines](#41-application-of-the-guidelines)\n    - [4.2. Guidelines for existing services and versioning of services](#42-guidelines-for-existing-services-and-versioning-of-services)\n    - [4.3. Requirements language](#43-requirements-language)\n    - [4.4. License](#44-license)\n  - [5. Taxonomy](#5-taxonomy)\n    - [5.1. Errors](#51-errors)\n    - [5.2. Faults](#52-faults)\n    - [5.3. Latency](#53-latency)\n    - [5.4. Time to complete](#54-time-to-complete)\n    - [5.5. Long running API faults](#55-long-running-api-faults)\n  - [6. Client guidance](#6-client-guidance)\n    - [6.1. Ignore rule](#61-ignore-rule)\n    - [6.2. Variable order rule](#62-variable-order-rule)\n    - [6.3. Silent fail rule](#63-silent-fail-rule)\n  - [7. Consistency fundamentals](#7-consistency-fundamentals)\n    - [7.1. URL structure](#71-url-structure)\n    - [7.2. URL length](#72-url-length)\n    - [7.3. Canonical identifier](#73-canonical-identifier)\n    - [7.4. Supported methods](#74-supported-methods)\n      - [7.4.1. POST](#741-post)\n      - [7.4.2. PATCH](#742-patch)\n      - [7.4.3. Creating resources via PATCH (UPSERT semantics)](#743-creating-resources-via-patch-upsert-semantics)\n      - [7.4.4. Options and link headers](#744-options-and-link-headers)\n    - [7.5. Standard request headers](#75-standard-request-headers)\n    - [7.6. Standard response headers](#76-standard-response-headers)\n    - [7.7. Custom headers](#77-custom-headers)\n    - [7.8. Specifying headers as query parameters](#78-specifying-headers-as-query-parameters)\n    - [7.9. PII parameters](#79-pii-parameters)\n    - [7.10. Response formats](#710-response-formats)\n      - [7.10.1. Clients-specified response format](#7101-clients-specified-response-format)\n      - [7.10.2. Error condition responses](#7102-error-condition-responses)\n        - [ErrorResponse : Object](#errorresponse--object)\n        - [Error : Object](#error--object)\n        - [InnerError : Object](#innererror--object)\n        - [Examples](#examples)\n    - [7.11. HTTP Status Codes](#711-http-status-codes)\n    - [7.12. Client library optional](#712-client-library-optional)\n  - [8. CORS](#8-cors)\n    - [8.1. Client guidance](#81-client-guidance)\n      - [8.1.1. Avoiding preflight](#811-avoiding-preflight)\n    - [8.2. Service guidance](#82-service-guidance)\n  - [9. Collections](#9-collections)\n    - [9.1. Item keys](#91-item-keys)\n    - [9.2. Serialization](#92-serialization)\n    - [9.3. Collection URL patterns](#93-collection-url-patterns)\n      - [9.3.1. Nested collections and properties](#931-nested-collections-and-properties)\n    - [9.4. Big collections](#94-big-collections)\n    - [9.5. Changing collections](#95-changing-collections)\n    - [9.6. Sorting collections](#96-sorting-collections)\n      - [9.6.1. Interpreting a sorting expression](#961-interpreting-a-sorting-expression)\n    - [9.7. Filtering](#97-filtering)\n      - [9.7.1. Filter operations](#971-filter-operations)\n      - [9.7.2. Operator examples](#972-operator-examples)\n      - [9.7.3. Operator precedence](#973-operator-precedence)\n    - [9.8. Pagination](#98-pagination)\n      - [9.8.1. Server-driven paging](#981-server-driven-paging)\n      - [9.8.2. Client-driven paging](#982-client-driven-paging)\n      - [9.8.3. Additional considerations](#983-additional-considerations)\n    - [9.9. Compound collection operations](#99-compound-collection-operations)\n    - [9.10. Empty Results](#910-empty-results)\n  - [10. Delta queries](#10-delta-queries)\n    - [10.1. Delta links](#101-delta-links)\n    - [10.2. Entity representation](#102-entity-representation)\n    - [10.3. Obtaining a delta link](#103-obtaining-a-delta-link)\n    - [10.4. Contents of a delta link response](#104-contents-of-a-delta-link-response)\n    - [10.5. Using a delta link](#105-using-a-delta-link)\n  - [11. JSON standardizations](#11-json-standardizations)\n    - [11.1. JSON formatting standardization for primitive types](#111-json-formatting-standardization-for-primitive-types)\n    - [11.2. Guidelines for dates and times](#112-guidelines-for-dates-and-times)\n      - [11.2.1. Producing dates](#1121-producing-dates)\n      - [11.2.2. Consuming dates](#1122-consuming-dates)\n      - [11.2.3. Compatibility](#1123-compatibility)\n    - [11.3. JSON serialization of dates and times](#113-json-serialization-of-dates-and-times)\n      - [11.3.1. The `DateLiteral` format](#1131-the-dateliteral-format)\n      - [11.3.2. Commentary on date formatting](#1132-commentary-on-date-formatting)\n    - [11.4. Durations](#114-durations)\n    - [11.5. Intervals](#115-intervals)\n    - [11.6. Repeating intervals](#116-repeating-intervals)\n  - [12. Versioning](#12-versioning)\n    - [12.1. Versioning formats](#121-versioning-formats)\n      - [12.1.1. Group versioning](#1211-group-versioning)\n        - [Examples of group versioning](#examples-of-group-versioning)\n    - [12.2. When to version](#122-when-to-version)\n    - [12.3. Definition of a breaking change](#123-definition-of-a-breaking-change)\n  - [13. Long running operations](#13-long-running-operations)\n    - [13.1. Resource based long running operations (RELO)](#131-resource-based-long-running-operations-relo)\n    - [13.2. Stepwise long running operations](#132-stepwise-long-running-operations)\n      - [13.2.1. PUT](#1321-put)\n      - [13.2.2. POST](#1322-post)\n      - [13.2.3. POST, hybrid model](#1323-post-hybrid-model)\n      - [13.2.4. Operations resource](#1324-operations-resource)\n      - [13.2.5. Operation resource](#1325-operation-resource)\n        - [Percent complete](#percent-complete)\n        - [Target resource location](#target-resource-location)\n      - [13.2.6. Operation tombstones](#1326-operation-tombstones)\n      - [13.2.7. The typical flow, polling](#1327-the-typical-flow-polling)\n        - [Example of the typical flow, polling](#example-of-the-typical-flow-polling)\n      - [13.2.8. The typical flow, push notifications](#1328-the-typical-flow-push-notifications)\n        - [Example of the typical flow, push notifications existing subscription](#example-of-the-typical-flow-push-notifications-existing-subscription)\n      - [13.2.9. Retry-After](#1329-retry-after)\n    - [13.3. Retention policy for operation results](#133-retention-policy-for-operation-results)\n  - [14. Throttling, Quotas, and Limits](#14-throttling-quotas-and-limits)\n    - [14.1. Principles](#141-principles)\n    - [14.2. Return Codes (429 vs 503)](#142-return-codes-429-vs-503)\n    - [14.3. Retry-After and RateLimit Headers](#143-retry-after-and-ratelimit-headers)\n    - [14.4. Service Guidance](#144-service-guidance)\n      - [14.4.1. Responsiveness](#1441-responsiveness)\n      - [14.4.2. Rate Limits and Quotas](#1442-rate-limits-and-quotas)\n      - [14.4.3. Overloaded services](#1443-overloaded-services)\n      - [14.4.4. Example Response](#1444-example-response)\n    - [14.5. Caller Guidance](#145-caller-guidance)\n    - [14.6. Handling callers that ignore Retry-After headers](#146-handling-callers-that-ignore-retry-after-headers)\n  - [15. Push notifications via webhooks](#15-push-notifications-via-webhooks)\n    - [15.1. Scope](#151-scope)\n    - [15.2. Principles](#152-principles)\n    - [15.3. Types of subscriptions](#153-types-of-subscriptions)\n    - [15.4. Call sequences](#154-call-sequences)\n    - [15.5. Verifying subscriptions](#155-verifying-subscriptions)\n    - [15.6. Receiving notifications](#156-receiving-notifications)\n      - [15.6.1. Notification payload](#1561-notification-payload)\n    - [15.7. Managing subscriptions programmatically](#157-managing-subscriptions-programmatically)\n      - [15.7.1. Creating subscriptions](#1571-creating-subscriptions)\n      - [15.7.2. Updating subscriptions](#1572-updating-subscriptions)\n      - [15.7.3. Deleting subscriptions](#1573-deleting-subscriptions)\n      - [15.7.4. Enumerating subscriptions](#1574-enumerating-subscriptions)\n    - [15.8. Security](#158-security)\n  - [16. Unsupported requests](#16-unsupported-requests)\n    - [16.1. Essential guidance](#161-essential-guidance)\n    - [16.2. Feature allow list](#162-feature-allow-list)\n      - [16.2.1. Error response](#1621-error-response)\n  - [17. Naming guidelines](#17-naming-guidelines)\n    - [17.1. Approach](#171-approach)\n    - [17.2. Casing](#172-casing)\n    - [17.3. Names to avoid](#173-names-to-avoid)\n    - [17.4. Forming compound names](#174-forming-compound-names)\n    - [17.5. Identity properties](#175-identity-properties)\n    - [17.6. Date and time properties](#176-date-and-time-properties)\n    - [17.7. Name properties](#177-name-properties)\n    - [17.8. Collections and counts](#178-collections-and-counts)\n    - [17.9. Common property names](#179-common-property-names)\n  - [18. Appendix](#18-appendix)\n    - [18.1. Sequence diagram notes](#181-sequence-diagram-notes)\n      - [18.1.1. Push notifications, per user flow](#1811-push-notifications-per-user-flow)\n      - [18.1.2. Push notifications, firehose flow](#1812-push-notifications-firehose-flow)\n\n<!-- /TOC -->\n\n## 3. Introduction\nDevelopers access most Microsoft Cloud Platform resources via HTTP interfaces.\nAlthough each service typically provides language-specific frameworks to wrap their APIs, all of their operations eventually boil down to HTTP requests.\nMicrosoft must support a wide range of clients and services and cannot rely on rich frameworks being available for every development environment.\nThus, a goal of these guidelines is to ensure Microsoft REST APIs can be easily and consistently consumed by any client with basic HTTP support.\n\nTo 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.\nThis document establishes the guidelines to be followed by Microsoft REST API developers for developing such APIs consistently.\n\nThe benefits of consistency accrue in aggregate as well; consistency allows teams to leverage common code, patterns, documentation and design decisions.\n\nThese guidelines aim to achieve the following:\n- Define consistent practices and patterns for all API endpoints across Microsoft.\n- Adhere as closely as possible to accepted REST/HTTP best practices in the industry at-large. [\\*]\n- Make accessing Microsoft Services via REST interfaces easy for all application developers.\n- Allow service developers to leverage the prior work of other services to implement, test and document REST endpoints defined consistently.\n- Allow for partners (e.g., non-Microsoft entities) to use these guidelines for their own REST endpoint design.\n\n[\\*] 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.\nThe 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.*\n\n### 3.1. Recommended reading\nUnderstanding the philosophy behind the REST Architectural Style is recommended for developing good HTTP-based services.\nIf you are new to RESTful design, here are some good resources:\n\n[REST on Wikipedia][rest-on-wikipedia] -- Overview of common definitions and core ideas behind REST.\n\n[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\"\n\n[RFC 7231][rfc-7231] -- Defines the specification for HTTP/1.1 semantics, and is considered the authoritative resource.\n\n[REST in Practice][rest-in-practice] -- Book on the fundamentals of REST.\n\n## 4. Interpreting the guidelines\n### 4.1. Application of the guidelines\nThese guidelines are applicable to any REST API exposed publicly by Microsoft or any partner service.\nPrivate or internal APIs SHOULD also try to follow these guidelines because internal services tend to eventually be exposed publicly.\n Consistency is valuable to not only external customers but also internal service consumers, and these guidelines offer best practices useful for any service.\n\nThere are legitimate reasons for exemption from these guidelines.\nObviously, 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.\nSome services MAY also have special performance needs that require a different format, such as a binary protocol.\n\n### 4.2. Guidelines for existing services and versioning of services\nWe do not recommend making a breaking change to a service that predates these guidelines simply for the sake of compliance.\nThe service SHOULD try to become compliant at the next version release when compatibility is being broken anyway.\nWhen a service adds a new API, that API SHOULD be consistent with the other APIs of the same version.\nSo 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.\n\n### 4.3. Requirements language\nThe 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].\n\n### 4.4. License\n\nThis work is licensed under the Creative Commons Attribution 4.0 International License.\nTo 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.\n\n## 5. Taxonomy\nAs part of onboarding to Microsoft REST API Guidelines, services MUST comply with the taxonomy defined below.\n\n### 5.1. Errors\nErrors, or more specifically Service Errors, are defined as a client passing invalid data to the service and the service _correctly_  rejecting that data.\nExamples include invalid credentials, incorrect parameters, unknown version IDs, or similar.\nThese are generally \"4xx\" HTTP error codes and are the result of a client passing incorrect or invalid data.\n\nErrors do _not_ contribute to overall API availability.\n\n### 5.2. Faults\nFaults, or more specifically Service Faults, are defined as the service failing to correctly return in response to a valid client request.\nThese are generally \"5xx\" HTTP error codes.\n\nFaults _do_ contribute to the overall API availability.\n\nCalls that fail due to rate limiting or quota failures MUST NOT count as faults.\nCalls that fail as the result of a service fast-failing requests (often for its own protection) do count as faults.\n\n### 5.3. Latency\nLatency is defined as how long a particular API call takes to complete, measured as closely to the client as possible.\nThis metric applies to both synchronous and asynchronous APIs in the same way.\nFor long running calls, the latency is measured on the initial request and measures how long that call (not the overall operation) takes to complete.\n\n### 5.4. Time to complete\nServices that expose long operations MUST track \"Time to Complete\" metrics around those operations.\n\n### 5.5. Long running API faults\nFor 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.\nLong Running faults MUST roll up as faults into the overall Availability metrics.\n\n## 6. Client guidance\nTo ensure the best possible experience for clients talking to a REST service, clients SHOULD adhere to the following best practices:\n\n### 6.1. Ignore rule\nFor 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.\n\nSome services MAY add fields to responses without changing versions numbers.\nServices that do so MUST make this clear in their documentation and clients MUST ignore unknown fields.\n\n### 6.2. Variable order rule\nClients MUST NOT rely on the order in which data appears in JSON service responses.\nFor example, clients SHOULD be resilient to the reordering of fields within a JSON object.\nWhen supported by the service, clients MAY request that data be returned in a specific order.\nFor example, services MAY support the use of the _$orderBy_ querystring parameter to specify the order of elements within a JSON array.\nServices MAY also explicitly specify the ordering of some elements as part of the service contract.\nFor 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.\nClients MAY rely on ordering behavior explicitly identified by the service.\n\n### 6.3. Silent fail rule\nClients requesting OPTIONAL server functionality (such as optional headers) MUST be resilient to the server ignoring that particular functionality.\n\n## 7. Consistency fundamentals\n### 7.1. URL structure\nHumans SHOULD be able to easily read and construct URLs.\n\nThis facilitates discovery and eases adoption on platforms without a well-supported client library.\n\nAn example of a well-structured URL is:\n\n```\nhttps://api.contoso.com/v1.0/people/jdoe@contoso.com/inbox\n```\n\nAn example URL that is not friendly is:\n\n```\nhttps://api.contoso.com/EWS/OData/Users('jdoe@microsoft.com')/Folders('AAMkADdiYzI1MjUzLTk4MjQtNDQ1Yy05YjJkLWNlMzMzYmIzNTY0MwAuAAAAAACzMsPHYH6HQoSwfdpDx-2bAQCXhUk6PC1dS7AERFluCgBfAAABo58UAAA=')\n```\n\nA frequent pattern that comes up is the use of URLs as values.\nServices MAY use URLs as values.\nFor example, the following is acceptable:\n\n```\nhttps://api.contoso.com/v1.0/items?url=https://resources.contoso.com/shoes/fancy\n```\n\n### 7.2. URL length\nThe 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.\nFrom the RFC:\n\n> HTTP does not place a predefined limit on the length of a\n   request-line. [...] A server that receives a request-target longer than any URI it wishes to parse MUST respond\n   with a 414 (URI Too Long) status code.\n\nServices that can generate URLs longer than 2,083 characters MUST make accommodations for the clients they wish to support.\nHere are some sources for determining what target clients support:\n\n * [https://stackoverflow.com/a/417184](https://stackoverflow.com/a/417184)\n * [https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/](https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/)\n\nAlso note that some technology stacks have hard and adjustable URL limits, so keep this in mind as you design your services.\n\n### 7.3. Canonical identifier\nIn addition to friendly URLs, resources that can be moved or be renamed SHOULD expose a URL that contains a unique stable identifier.\nIt 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.\n\nThe stable identifier is not required to be a GUID.\n\nAn example of a URL containing a canonical identifier is:\n\n```\nhttps://api.contoso.com/v1.0/people/7011042402/inbox\n```\n\n### 7.4. Supported methods\nOperations MUST use the proper HTTP methods whenever possible, and operation idempotency MUST be respected.\nHTTP methods are frequently referred to as the HTTP verbs.\nThe terms are synonymous in this context, however the HTTP specification uses the term method.\n\nBelow is a list of methods that Microsoft REST services SHOULD support.\nNot all resources will support all methods, but all resources using the methods below MUST conform to their usage.\n\nMethod  | Description                                                                                                                | Is Idempotent\n------- | -------------------------------------------------------------------------------------------------------------------------- | -------------\nGET     | Return the current value of an object                                                                                      | True\nPUT     | Replace an object, or create a named object, when applicable                                                               | True\nDELETE  | Delete an object                                                                                                           | True\nPOST    | Create a new object based on the data provided, or submit a command                                                        | False\nHEAD    | Return metadata of an object for a GET response. Resources that support the GET method MAY support the HEAD method as well | True\nPATCH   | Apply a partial update to an object                                                                                        | False\nOPTIONS | Get information about a request; see below for details.                                                                    | True\n\n<small>Table 1</small>\n\n#### 7.4.1. POST\nPOST operations SHOULD support the Location response header to specify the location of any created resource that was not explicitly named, via the Location header.\n\nAs an example, imagine a service that allows creation of hosted servers, which will be named by the service:\n\n```http\nPOST http://api.contoso.com/account1/servers\n```\n\nThe response would be something like:\n\n```http\n201 Created\nLocation: http://api.contoso.com/account1/servers/server321\n```\n\nWhere \"server321\" is the service-allocated server name.\n\nServices MAY also return the full metadata for the created item in the response.\n\n#### 7.4.2. PATCH\nPATCH has been standardized by IETF as the method to be used for updating an existing object incrementally (see [RFC 5789][rfc-5789]).\nMicrosoft REST API Guidelines compliant APIs SHOULD support PATCH.\n\n#### 7.4.3. Creating resources via PATCH (UPSERT semantics)\nServices that allow callers to specify key values on create SHOULD support UPSERT semantics, and those that do MUST support creating resources using PATCH.\nBecause PUT is defined as a complete replacement of the content, it is dangerous for clients to use PUT to modify data.\nClients that do not understand (and hence ignore) properties on a resource are not likely to provide them on a PUT when trying to update a resource, hence such properties could be inadvertently removed.\nServices MAY optionally support PUT to update existing resources, but if they do they MUST use replacement semantics (that is, after the PUT, the resource's properties MUST match what was provided in the request, including deleting any server properties that were not provided).\n\nUnder UPSERT semantics, a PATCH call to a nonexistent resource is handled by the server as a \"create\", and a PATCH call to an existing resource is handled as an \"update\". To ensure that an update request is not treated as a create or vice versa, the client MAY specify precondition HTTP headers in the request.\nThe service MUST NOT treat a PATCH request as an insert if it contains an If-Match header and MUST NOT treat a PATCH request as an update if it contains an If-None-Match header with a value of \"*\".\n\nIf a service does not support UPSERT, then a PATCH call against a resource that does not exist MUST result in an HTTP \"409 Conflict\" error.\n\n#### 7.4.4. Options and link headers\nOPTIONS allows a client to retrieve information about a resource, at a minimum by returning the Allow header denoting the valid methods for this resource.\n\nIn addition, services SHOULD include a Link header (see [RFC 5988][rfc-5988]) to point to documentation for the resource in question:\n\n```http\nLink: <{help}>; rel=\"help\"\n```\n\nWhere {help} is the URL to a documentation resource.\n\nFor examples on use of OPTIONS, see [preflighting CORS cross-domain calls][cors-preflight].\n\n### 7.5. Standard request headers\nThe table of request headers below SHOULD be used by Microsoft REST API Guidelines services.\nUsing these headers is not mandated, but if used they MUST be used consistently.\n\nAll header values MUST follow the syntax rules set forth in the specification where the header field is defined.\nMany HTTP headers are defined in [RFC7231][rfc-7231], however a complete list of approved headers can be found in the [IANA Header Registry][IANA-headers].\"\n\nHeader                            | Type                                  | Description\n--------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\nAuthorization                     | String                                           | Authorization header for the request\nDate                              | Date                                             | Timestamp of the request, based on the client's clock, in [RFC 5322][rfc-5322-3-3] date and time format.  The server SHOULD NOT make any assumptions about the accuracy of the client's clock.  This header MAY be included in the request, but MUST be in this format when supplied.  Greenwich Mean Time (GMT) MUST be used as the time zone reference for this header when it is provided.  For example: `Wed, 24 Aug 2016 18:41:30 GMT`.  Note that GMT is exactly equal to UTC (Coordinated Universal Time) for this purpose.\nAccept                            | Content type                                     | The requested content type for the response such as: <ul><li>application/xml</li><li>text/xml</li><li>application/json</li><li>text/javascript (for JSONP)</li></ul>Per the HTTP guidelines, this is just a hint and responses MAY have a different content type, such as a blob fetch where a successful response will just be the blob stream as the payload. For services following OData, the preference order specified in OData SHOULD be followed.\nAccept-Encoding                   | Gzip, deflate                                    | REST endpoints SHOULD support GZIP and DEFLATE encoding, when applicable. For very large resources, services MAY ignore and return uncompressed data.\nAccept-Language                   | \"en\", \"es\", etc.                                 | Specifies the preferred language for the response. Services are not required to support this, but if a service supports localization it MUST do so through the Accept-Language header.\nAccept-Charset                    | Charset type like \"UTF-8\"                        | Default is UTF-8, but services SHOULD be able to handle ISO-8859-1.\nContent-Type                      | Content type                                     | Mime type of request body (PUT/POST/PATCH)\nPrefer                            | return=minimal, return=representation            | If the return=minimal preference is specified, services SHOULD return an empty body in response to a successful insert or update. If return=representation is specified, services SHOULD return the created or updated resource in the response. Services SHOULD support this header if they have scenarios where clients would sometimes benefit from responses, but sometimes the response would impose too much of a hit on bandwidth.\nIf-Match, If-None-Match, If-Range | String                                           | Services that support updates to resources using optimistic concurrency control MUST support the If-Match header to do so. Services MAY also use other headers related to ETags as long as they follow the HTTP specification.\n\n### 7.6. Standard response headers\nServices SHOULD return the following response headers, except where noted in the \"required\" column.\n\nResponse Header    | Required                                      | Description\n------------------ | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\nDate               | All responses                                 | Timestamp the response was processed, based on the server's clock, in [RFC 5322][rfc-5322-3-3] date and time format.  This header MUST be included in the response.  Greenwich Mean Time (GMT) MUST be used as the time zone reference for this header.  For example: `Wed, 24 Aug 2016 18:41:30 GMT`. Note that GMT is exactly equal to UTC (Coordinated Universal Time) for this purpose.\nContent-Type       | All responses                                 | The content type\nContent-Encoding   | All responses                                 | GZIP or DEFLATE, as appropriate\nPreference-Applied | When specified in request                     | Whether a preference indicated in the Prefer request header was applied\nETag               | When the requested resource has an entity tag | The ETag response-header field provides the current value of the entity tag for the requested variant. Used with If-Match, If-None-Match and If-Range to implement optimistic concurrency control.\n\n### 7.7. Custom headers\nCustom headers MUST NOT be required for the basic operation of a given API.\n\nSome of the guidelines in this document prescribe the use of nonstandard HTTP headers.\nIn addition, some services MAY need to add extra functionality, which is exposed via HTTP headers.\nThe following guidelines help maintain consistency across usage of custom headers.\n\nHeaders that are not standard HTTP headers MUST have one of two formats:\n\n1. A generic format for headers that are registered as \"provisional\" with IANA ([RFC 3864][rfc-3864])\n2. A scoped format for headers that are too usage-specific for registration\n\nThese two formats are described below.\n\n### 7.8. Specifying headers as query parameters\nSome headers pose challenges for some scenarios such as AJAX clients, especially when making cross-domain calls where adding headers MAY not be supported.\nAs such, some headers MAY be accepted as Query Parameters in addition to headers, with the same naming as the header:\n\nNot all headers make sense as query parameters, including most standard HTTP headers.\n\nThe criteria for considering when to accept headers as parameters are:\n\n1. Any custom headers MUST be also accepted as parameters.\n2. Required standard headers MAY be accepted as parameters.\n3. Required headers with security sensitivity (e.g., Authorization header) MIGHT NOT be appropriate as parameters; the service owner SHOULD evaluate these on a case-by-case basis.\n\nThe one exception to this rule is the Accept header.\nIt's common practice to use a scheme with simple names instead of the full functionality described in the HTTP specification for Accept.\n\n### 7.9. PII parameters\nConsistent with their organization's privacy policy, clients SHOULD NOT transmit personally identifiable information (PII) parameters in the URL (as part of path or query string) because this information can be inadvertently exposed via client, network, and server logs and other mechanisms.\n\nConsequently, a service SHOULD accept PII parameters transmitted as headers.\n\nHowever, there are many scenarios where the above recommendations cannot be followed due to client or software limitations.\nTo address these limitations, services SHOULD also accept these PII parameters as part of the URL consistent with the rest of these guidelines.\n\nServices that accept PII parameters -- whether in the URL or as headers -- SHOULD be compliant with privacy policy specified by their organization's engineering leadership.\nThis will typically include recommending that clients prefer headers for transmission and implementations adhere to special precautions to ensure that logs and other service data collection are properly handled.\n\n### 7.10. Response formats\nFor organizations to have a successful platform, they must serve data in formats developers are accustomed to using, and in consistent ways that allow developers to handle responses with common code.\n\nWeb-based communication, especially when a mobile or other low-bandwidth client is involved, has moved quickly in the direction of JSON for a variety of reasons, including its tendency to be lighter weight and its ease of consumption with JavaScript-based clients.\n\nJSON property names SHOULD be camelCased.\n\nServices SHOULD provide JSON as the default encoding.\n\n#### 7.10.1. Clients-specified response format\nIn HTTP, response format SHOULD be requested by the client using the Accept header.\nThis is a hint, and the server MAY ignore it if it chooses to, even if this isn't typical of well-behaved servers.\nClients MAY send multiple Accept headers and the service MAY choose one of them.\n\nThe default response format (no Accept header provided) SHOULD be application/json, and all services MUST support application/json.\n\nAccept Header    | Response type                      | Notes\n---------------- | ---------------------------------- | -------------------------------------------\napplication/json | Payload SHOULD be returned as JSON | Also accept text/javascript for JSONP cases\n\n```http\nGET https://api.contoso.com/v1.0/products/user\nAccept: application/json\n```\n\n#### 7.10.2. Error condition responses\nFor non-success conditions, developers SHOULD be able to write one piece of code that handles errors consistently across different Microsoft REST API Guidelines services.\nThis allows building of simple and reliable infrastructure to handle exceptions as a separate flow from successful responses.\nThe following is based on the OData v4 JSON spec.\nHowever, it is very generic and does not require specific OData constructs.\nAPIs SHOULD use this format even if they are not using other OData constructs.\n\nThe error response MUST be a single JSON object.\nThis object MUST have a name/value pair named \"error\". The value MUST be a JSON object.\n\nThis object MUST contain name/value pairs with the names \"code\" and \"message\", and it MAY contain name/value pairs with the names \"target\", \"details\" and \"innererror.\"\n\nThe value for the \"code\" name/value pair is a language-independent string.\nIts value is a service-defined error code that SHOULD be human-readable.\nThis code serves as a more specific indicator of the error than the HTTP error code specified in the response.\nServices SHOULD have a relatively small number (about 20) of possible values for \"code\", and all clients MUST be capable of handling all of them.\nMost services will require a much larger number of more specific error codes, which are not interesting to all clients.\nThese error codes SHOULD be exposed in the \"innererror\" name/value pair as described below.\nIntroducing a new value for \"code\" that is visible to existing clients is a breaking change and requires a version increase.\nServices can avoid breaking changes by adding new error codes to \"innererror\" instead.\n\nThe value for the \"message\" name/value pair MUST be a human-readable representation of the error.\nIt is intended as an aid to developers and is not suitable for exposure to end users.\nServices wanting to expose a suitable message for end users MUST do so through an [annotation][odata-json-annotations] or custom property.\nServices SHOULD NOT localize \"message\" for the end user, because doing so might make the value unreadable to the app developer who may be logging the value, as well as make the value less searchable on the Internet.\n\nThe value for the \"target\" name/value pair is the target of the particular error (e.g., the name of the property in error).\n\nThe value for the \"details\" name/value pair MUST be an array of JSON objects that MUST contain name/value pairs for \"code\" and \"message\", and MAY contain a name/value pair for \"target\", as described above.\nThe objects in the \"details\" array usually represent distinct, related errors that occurred during the request.\nSee example below.\n\nThe value for the \"innererror\" name/value pair MUST be an object.\nThe contents of this object are service-defined.\nServices wanting to return more specific errors than the root-level code MUST do so by including a name/value pair for \"code\" and a nested \"innererror\". Each nested \"innererror\" object represents a higher level of detail than its parent.\nWhen evaluating errors, clients MUST traverse through all of the nested \"innererrors\" and choose the deepest one that they understand.\nThis scheme allows services to introduce new error codes anywhere in the hierarchy without breaking backwards compatibility, so long as old error codes still appear.\nThe service MAY return different levels of depth and detail to different callers.\nFor example, in development environments, the deepest \"innererror\" MAY contain internal information that can help debug the service.\nTo guard against potential security concerns around information disclosure, services SHOULD take care not to expose too much detail unintentionally.\nError objects MAY also include custom server-defined name/value pairs that MAY be specific to the code.\nError types with custom server-defined properties SHOULD be declared in the service's metadata document.\nSee example below.\n\nError responses MAY contain [annotations][odata-json-annotations] in any of their JSON objects.\n\nWe recommend that for any transient errors that may be retried, services SHOULD include a Retry-After HTTP header indicating the minimum number of seconds that clients SHOULD wait before attempting the operation again.\n\n##### ErrorResponse : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`error` | Error | ✔ | The error object.\n\n##### Error : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`code` | String | ✔ | One of a server-defined set of error codes.\n`message` | String | ✔ | A human-readable representation of the error.\n`target` | String |  | The target of the error.\n`details` | Error[] |  | An array of details about specific errors that led to this reported error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n\n##### InnerError : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`code` | String |  | A more specific error code than was provided by the containing error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n\n##### Examples\n\nExample of \"innererror\":\n\n```json\n{\n  \"error\": {\n    \"code\": \"BadArgument\",\n    \"message\": \"Previous passwords may not be reused\",\n    \"target\": \"password\",\n    \"innererror\": {\n      \"code\": \"PasswordError\",\n      \"innererror\": {\n        \"code\": \"PasswordDoesNotMeetPolicy\",\n        \"minLength\": \"6\",\n        \"maxLength\": \"64\",\n        \"characterTypes\": [\"lowerCase\",\"upperCase\",\"number\",\"symbol\"],\n        \"minDistinctCharacterTypes\": \"2\",\n        \"innererror\": {\n          \"code\": \"PasswordReuseNotAllowed\"\n        }\n      }\n    }\n  }\n}\n```\n\nIn this example, the most basic error code is \"BadArgument\", but for clients that are interested, there are more specific error codes in \"innererror.\"\nThe \"PasswordReuseNotAllowed\" code may have been added by the service at a later date, having previously only returned \"PasswordDoesNotMeetPolicy.\"\nExisting clients do not break when the new error code is added, but new clients MAY take advantage of it.\nThe \"PasswordDoesNotMeetPolicy\" error also includes additional name/value pairs that allow the client to determine the server's configuration, validate the user's input programmatically, or present the server's constraints to the user within the client's own localized messaging.\n\nExample of \"details\":\n\n```json\n{\n  \"error\": {\n    \"code\": \"BadArgument\",\n    \"message\": \"Multiple errors in ContactInfo data\",\n    \"target\": \"ContactInfo\",\n    \"details\": [\n      {\n        \"code\": \"NullValue\",\n        \"target\": \"PhoneNumber\",\n        \"message\": \"Phone number must not be null\"\n      },\n      {\n        \"code\": \"NullValue\",\n        \"target\": \"LastName\",\n        \"message\": \"Last name must not be null\"\n      },\n      {\n        \"code\": \"MalformedValue\",\n        \"target\": \"Address\",\n        \"message\": \"Address is not valid\"\n      }\n    ]\n  }\n}\n```\n\nIn this example there were multiple problems with the request, with each individual error listed in \"details.\"\n\n### 7.11. HTTP Status Codes\nStandard HTTP Status Codes SHOULD be used; see the HTTP Status Code definitions for more information.\n\n### 7.12. Client library optional\nDevelopers MUST be able to develop on a wide variety of platforms and languages, such as Windows, macOS, Linux, C#, Python, Node.js, and Ruby.\n\nServices SHOULD be able to be accessed from simple HTTP tools such as curl without significant effort.\n\nService developer portals SHOULD provide the equivalent of \"Get Developer Token\" to facilitate experimentation and curl support.\n\n## 8. CORS\nServices compliant with the Microsoft REST API Guidelines MUST support [CORS (Cross Origin Resource Sharing)][cors].\nServices SHOULD support an allowed origin of CORS * and enforce authorization through valid OAuth tokens.\nServices SHOULD NOT support user credentials with origin validation.\nThere MAY be exceptions for special cases.\n\n### 8.1. Client guidance\nWeb developers usually don't need to do anything special to take advantage of CORS.\nAll of the handshake steps happen invisibly as part of the standard XMLHttpRequest calls they make.\n\nMany other platforms, such as .NET, have integrated support for CORS.\n\n#### 8.1.1. Avoiding preflight\nBecause the CORS protocol can trigger preflight requests that add additional round trips to the server, performance-critical apps might be interested in avoiding them.\nThe spirit behind CORS is to avoid preflight for any simple cross-domain requests that old non-CORS-capable browsers were able to make.\nAll other requests require preflight.\n\nA request is \"simple\" and avoids preflight if its method is GET, HEAD or POST, and if it doesn't contain any request headers besides Accept, Accept-Language and Content-Language.\nFor POST requests, the Content-Type header is also allowed, but only if its value is \"application/x-www-form-urlencoded\", \"multipart/form-data\" or \"text/plain.\"\nFor any other headers or values, a preflight request will happen.\n\n### 8.2. Service guidance\n At minimum, services MUST:\n- Understand the Origin request header that browsers send on cross-domain requests, and the Access-Control-Request-Method request header that they send on preflight OPTIONS requests that check for access.\n- If the Origin header is present in a request:\n  - If the request uses the OPTIONS method and contains the Access-Control-Request-Method header, then it is a preflight request intended to probe for access before the actual request. Otherwise, it is an actual request. For preflight requests, beyond performing the steps below to add headers, services MUST perform no additional processing and MUST return a 200 OK. For non-preflight requests, the headers below are added in addition to the request's regular processing.\n  - Add an Access-Control-Allow-Origin header to the response, containing the same value as the Origin request header. Note that this requires services to dynamically generate the header value. Resources that do not require cookies or any other form of [user credentials][cors-user-credentials] MAY respond with a wildcard asterisk (*) instead. Note that the wildcard is acceptable here only, and not for any of the other headers described below.\n  - If the caller requires access to a response header that is not in the set of [simple response headers][cors-simple-headers] (Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma), then add an Access-Control-Expose-Headers header containing the list of additional response header names the client should have access to.\n  - If the request requires cookies, then add an Access-Control-Allow-Credentials header set to \"true.\"\n  - If the request was a preflight request (see first bullet), then the service MUST:\n    - Add an Access-Control-Allow-Headers response header containing the list of request header names the client is permitted to use. This list need only contain headers that are not in the set of [simple request headers][cors-simple-headers] (Accept, Accept-Language, Content-Language). If there are no restrictions on headers the service accepts, the service MAY simply return the same value as the Access-Control-Request-Headers header sent by the client.\n    - Add an Access-Control-Allow-Methods response header containing the list of HTTP methods the caller is permitted to use.\n\nAdd an Access-Control-Max-Age pref response header containing the number of seconds for which this preflight response is valid (and hence can be avoided before subsequent actual requests). Note that while it is customary to use a large value like 2592000 (30 days), many browsers self-impose a much lower limit (e.g., five minutes).\n\nBecause browser preflight response caches are notoriously weak, the additional round trip from a preflight response hurts performance.\nServices used by interactive Web clients where performance is critical SHOULD avoid patterns that cause a preflight request\n- For GET and HEAD calls, avoid requiring request headers that are not part of the simple set above. Allow them to be provided as query parameters instead.\n  - The Authorization header is not part of the simple set, so the authentication token MUST be sent through the \"access_token\" query parameter instead, for resources requiring authentication. Note that passing authentication tokens in the URL is not recommended, because it can lead to the token getting recorded in server logs and exposed to anyone with access to those logs. Services that accept authentication tokens through the URL MUST take steps to mitigate the security risks, such as using short-lived authentication tokens, suppressing the auth token from getting logged, and controlling access to server logs.\n\n- Avoid requiring cookies. XmlHttpRequest will only send cookies on cross-domain requests if the \"withCredentials\" attribute is set; this also causes a preflight request.\n  - Services that require cookie-based authentication MUST use a \"dynamic canary\" to secure all APIs that accept cookies.\n\n- For POST calls, prefer simple Content-Types in the set of (\"application/x-www-form-urlencoded\", \"multipart/form-data\", \"text/plain\") where applicable. Any other Content-Type will induce a preflight request.\n  - Services MUST NOT contravene other API recommendations in the name of avoiding CORS preflight requests. In particular, in accordance with recommendations, most POST requests will actually require a preflight request due to the Content-Type.\n  - If eliminating preflight is critical, then a service MAY support alternative mechanisms for data transfer, but the RECOMMENDED approach MUST also be supported.\n\nIn addition, when appropriate services MAY support the JSONP pattern for simple, GET-only cross-domain access.\nIn JSONP, services take a parameter indicating the format (_$format=json_) and a parameter indicating a callback (_$callback=someFunc_), and return a text/javascript document containing the JSON response wrapped in a function call with the indicated name.\nMore on JSONP at Wikipedia: [JSONP](https://en.wikipedia.org/wiki/JSONP).\n\n## 9. Collections\n### 9.1. Item keys\nServices MAY support durable identifiers for each item in the collection, and that identifier SHOULD be represented in JSON as \"id\". These durable identifiers are often used as item keys.\n\nCollections that support durable identifiers MAY support delta queries.\n\n### 9.2. Serialization\nCollections are represented in JSON using standard array notation.\n\n### 9.3. Collection URL patterns\nCollections are located directly under the service root when they are top level, or as a segment under another resource when scoped to that resource.\n\nFor example:\n\n```http\nGET https://api.contoso.com/v1.0/people\n```\n\nWhenever possible, services MUST support the \"/\" pattern.\nFor example:\n\n```http\nGET https://{serviceRoot}/{collection}/{id}\n```\n\nWhere:\n- {serviceRoot} – the combination of host (site URL) + the root path to the service\n- {collection} – the name of the collection, unabbreviated, pluralized\n- {id} – the value of the unique id property. When using the \"/\" pattern this MUST be the raw string/number/guid value with no quoting but properly escaped to fit in a URL segment.\n\n#### 9.3.1. Nested collections and properties\nCollection items MAY contain other collections.\nFor example, a user collection MAY contain user resources that have multiple addresses:\n\n```http\nGET https://api.contoso.com/v1.0/people/123/addresses\n```\n\n```json\n{\n  \"value\": [\n    { \"street\": \"1st Avenue\", \"city\": \"Seattle\" },\n    { \"street\": \"124th Ave NE\", \"city\": \"Redmond\" }\n  ]\n}\n```\n\n### 9.4. Big collections\nAs data grows, so do collections.\nPlanning for pagination is important for all services.\nTherefore, when multiple pages are available, the serialization payload MUST contain the opaque URL for the next page as appropriate.\nRefer to the paging guidance for more details.\n\nClients MUST be resilient to collection data being either paged or nonpaged for any given request.\n\n```json\n{\n  \"value\":[\n    { \"id\": \"Item 1\",\"price\": 99.95,\"sizes\": null},\n    { … },\n    { … },\n    { \"id\": \"Item 99\",\"price\": 59.99,\"sizes\": null}\n  ],\n  \"@nextLink\": \"{opaqueUrl}\"\n}\n```\n\n### 9.5. Changing collections\nPOST requests are not idempotent.\nThis means that two POST requests sent to a collection resource with exactly the same payload MAY lead to multiple items being created in that collection.\nThis is often the case for insert operations on items with a server-side generated id.\n\nFor example, the following request:\n\n```http\nPOST https://api.contoso.com/v1.0/people\n```\n\nWould lead to a response indicating the location of the new collection item:\n\n```http\n201 Created\nLocation: https://api.contoso.com/v1.0/people/123\n```\n\nAnd once executed again, would likely lead to another resource:\n\n```http\n201 Created\nLocation: https://api.contoso.com/v1.0/people/124\n```\n\nWhile a PUT request would require the indication of the collection item with the corresponding key instead:\n\n```http\nPUT https://api.contoso.com/v1.0/people/123\n```\n\n### 9.6. Sorting collections\nThe results of a collection query MAY be sorted based on property values.\nThe property is determined by the value of the _$orderBy_ query parameter.\n\nThe value of the _$orderBy_ parameter contains a comma-separated list of expressions used to sort the items.\nA special case of such an expression is a property path terminating on a primitive property.\n\nThe expression MAY include the suffix \"asc\" for ascending or \"desc\" for descending, separated from the property name by one or more spaces.\nIf \"asc\" or \"desc\" is not specified, the service MUST order by the specified property in ascending order.\n\nNULL values MUST sort as \"less than\" non-NULL values.\n\nItems MUST be sorted by the result values of the first expression, and then items with the same value for the first expression are sorted by the result value of the second expression, and so on.\nThe sort order is the inherent order for the type of the property.\n\nFor example:\n\n```http\nGET https://api.contoso.com/v1.0/people?$orderBy=name\n```\n\nWill return all people sorted by name in ascending order.\n\nFor example:\n\n```http\nGET https://api.contoso.com/v1.0/people?$orderBy=name desc\n```\n\nWill return all people sorted by name in descending order.\n\nSub-sorts can be specified by a comma-separated list of property names with OPTIONAL direction qualifier.\n\nFor example:\n\n```http\nGET https://api.contoso.com/v1.0/people?$orderBy=name desc,hireDate\n```\n\nWill return all people sorted by name in descending order and a secondary sort order of hireDate in ascending order.\n\nSorting MUST compose with filtering such that:\n\n```http\nGET https://api.contoso.com/v1.0/people?$filter=name eq 'david'&$orderBy=hireDate\n```\n\nWill return all people whose name is David sorted in ascending order by hireDate.\n\n#### 9.6.1. Interpreting a sorting expression\nSorting parameters MUST be consistent across pages, as both client and server-side paging is fully compatible with sorting.\n\nIf a service does not support sorting by a property named in a _$orderBy_ expression, the service MUST respond with an error message as defined in the Responding to Unsupported Requests section.\n\n### 9.7. Filtering\nThe _$filter_ querystring parameter allows clients to filter a collection of resources that are addressed by a request URL.\nThe expression specified with _$filter_ is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response.\nResources for which the expression evaluates to false or to null, or which reference properties that are unavailable due to permissions, are omitted from the response.\n\nExample: return all Products whose Price is less than $10.00\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=price lt 10.00\n```\n\nThe value of the _$filter_ option is a Boolean expression.\n\n#### 9.7.1. Filter operations\nServices that support _$filter_ SHOULD support the following minimal set of operations.\n\nOperator             | Description           | Example\n-------------------- | --------------------- | -----------------------------------------------------\nComparison Operators |                       |\neq                   | Equal                 | city eq 'Redmond'\nne                   | Not equal             | city ne 'London'\ngt                   | Greater than          | price gt 20\nge                   | Greater than or equal | price ge 10\nlt                   | Less than             | price lt 20\nle                   | Less than or equal    | price le 100\nLogical Operators    |                       |\nand                  | Logical and           | price le 200 and price gt 3.5\nor                   | Logical or            | price le 3.5 or price gt 200\nnot                  | Logical negation      | not price le 3.5\nGrouping Operators   |                       |\n( )                  | Precedence grouping   | (priority eq 1 or city eq 'Redmond') and price gt 100\n\n#### 9.7.2. Operator examples\nThe following examples illustrate the use and semantics of each of the logical operators.\n\nExample: all products with a name equal to 'Milk'\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk'\n```\n\nExample: all products with a name not equal to 'Milk'\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=name ne 'Milk'\n```\n\nExample: all products with the name 'Milk' that also have a price less than 2.55:\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk' and price lt 2.55\n```\n\nExample: all products that either have the name 'Milk' or have a price less than 2.55:\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=name eq 'Milk' or price lt 2.55\n```\n\nExample: all products that have the name 'Milk' or 'Eggs' and have a price less than 2.55:\n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55\n```\n\n#### 9.7.3. Operator precedence\nServices MUST use the following operator precedence for supported operators when evaluating _$filter_ expressions.\nOperators are listed by category in order of precedence from highest to lowest.\nOperators in the same category have equal precedence:\n\n| Group           | Operator | Description           |\n|:----------------|:---------|:----------------------|\n| Grouping        | ( )      | Precedence grouping   |\n| Unary           | not      | Logical Negation      |\n| Relational      | gt       | Greater Than          |\n|                 | ge       | Greater than or Equal |\n|                 | lt       | Less Than             |\n|                 | le       | Less than or Equal    |\n| Equality        | eq       | Equal                 |\n|                 | ne       | Not Equal             |\n| Conditional AND | and      | Logical And           |\n| Conditional OR  | or       | Logical Or            |\n\n### 9.8. Pagination\nRESTful APIs that return collections MAY return partial sets.\nConsumers of these services MUST expect partial result sets and correctly page through to retrieve an entire set.\n\nThere are two forms of pagination that MAY be supported by RESTful APIs.\nServer-driven paging mitigates against denial-of-service attacks by forcibly paginating a request over multiple response payloads.\nClient-driven paging enables clients to request only the number of resources that it can use at a given time.\n\nSorting and Filtering parameters MUST be consistent across pages, because both client- and server-side paging is fully compatible with both filtering and sorting.\n\n#### 9.8.1. Server-driven paging\nPaginated responses MUST indicate a partial result by including a continuation token in the response.\nThe absence of a continuation token means that no additional pages are available.\n\nClients MUST treat the continuation URL as opaque, which means that query options may not be changed while iterating over a set of partial results.\n\nExample:\n\n```http\nGET http://api.contoso.com/v1.0/people HTTP/1.1\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  ...,\n  \"value\": [...],\n  \"@nextLink\": \"{opaqueUrl}\"\n}\n```\n\n#### 9.8.2. Client-driven paging\nClients MAY use _$top_ and _$skip_ query parameters to specify a number of results to return and an offset into the collection.\n\nThe server SHOULD honor the values specified by the client; however, clients MUST be prepared to handle responses that contain a different page size or contain a continuation token.\n\nWhen both _$top_ and _$skip_ are given by a client, the server SHOULD first apply _$skip_ and then _$top_ on the collection.\n\nNote: If the server can't honor _$top_ and/or _$skip_, the server MUST return an error to the client informing about it instead of just ignoring the query options.\nThis will avoid the risk of the client making assumptions about the data returned.\n\nExample:\n\n```http\nGET http://api.contoso.com/v1.0/people?$top=5&$skip=2 HTTP/1.1\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  ...,\n  \"value\": [...]\n}\n```\n\n#### 9.8.3. Additional considerations\n**Stable order prerequisite:** Both forms of paging depend on the collection of items having a stable order.\nThe server MUST supplement any specified order criteria with additional sorts (typically by key) to ensure that items are always ordered consistently.\n\n**Missing/repeated results:** Even if the server enforces a consistent sort order, results MAY be missing or repeated based on creation or deletion of other resources.\nClients MUST be prepared to deal with these discrepancies.\nThe server SHOULD always encode the record ID of the last read record, helping the client in the process of managing repeated/missing results.\n\n**Combining client- and server-driven paging:** Note that client-driven paging does not preclude server-driven paging.\nIf the page size requested by the client is larger than the default page size supported by the server, the expected response would be the number of results specified by the client, paginated as specified by the server paging settings.\n\n**Page Size:** Clients MAY request server-driven paging with a specific page size by specifying a _$maxpagesize_ preference.\nThe server SHOULD honor this preference if the specified page size is smaller than the server's default page size.\n\n**Paginating embedded collections:** It is possible for both client-driven paging and server-driven paging to be applied to embedded collections.\nIf a server paginates an embedded collection, it MUST include additional continuation tokens as appropriate.\n\n**Recordset count:** Developers who want to know the full number of records across all pages, MAY include the query parameter _$count=true_ to tell the server to include the count of items in the response.\n\n### 9.9. Compound collection operations\nFiltering, Sorting and Pagination operations MAY all be performed against a given collection.\nWhen these operations are performed together, the evaluation order MUST be:\n\n1. **Filtering**. This includes all range expressions performed as an AND operation.\n2. **Sorting**. The potentially filtered list is sorted according to the sort criteria.\n3. **Pagination**. The materialized paginated view is presented over the filtered, sorted list. This applies to both server-driven pagination and client-driven pagination.\n\n### 9.10. Empty Results\nWhen a filter is performed on a collection and the result set is empty you MUST respond with a valid response body and a 200 response code. \nIn this example the filters supplied by the client resulted in a empty result set. \nThe response body is returned as normal and the _value_ attribute is set to a empty collection. \nA client MAY be expecting metadata attributes like _maxItems_ based on the format of your responses to similar calls which produced results. \nYou SHOULD maintain consistency in your API whenever possible. \n\n```http\nGET https://api.contoso.com/v1.0/products?$filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  ...,\n  \"maxItems\": 0,\n  \"value\": []\n}\n```\n\n## 10. Delta queries\nServices MAY choose to support delta queries.\n\n### 10.1. Delta links\nDelta links are opaque, service-generated links that the client uses to retrieve subsequent changes to a result.\n\nAt a conceptual level delta links are based on a defining query that describes the set of results for which changes are being tracked.\nThe delta link encodes the collection of entities for which changes are being tracked, along with a starting point from which to track changes.\n\nIf the query contains a filter, the response MUST include only changes to entities matching the specified criteria.\nThe key principles of the Delta Query are:\n- Every item in the set MUST have a persistent identifier. That identifier SHOULD be represented as \"id\". This identifier is a service defined opaque string that MAY be used by the client to track object across calls.\n- The delta MUST contain an entry for each entity that newly matches the specified criteria, and MUST contain a \"@removed\" entry for each entity that no longer matches the criteria.\n- Re-evaluate the query and compare it to original set of results; every entry uniquely in the current set MUST be returned as an Add operation, and every entry uniquely in the original set MUST be returned as a \"remove\" operation.\n- Each entity that previously did not match the criteria but matches it now MUST be returned as an \"add\"; conversely, each entity that previously matched the query but no longer does MUST be returned as a \"@removed\" entry.\n- Entities that have changed MUST be included in the set using their standard representation.\n- Services MAY add additional metadata to the \"@removed\" node, such as a reason for removal, or a \"removed at\" timestamp. We recommend teams coordinate with the Microsoft REST API Guidelines Working Group on extensions to help maintain consistency.\n\nThe delta link MUST NOT encode any client top or skip value.\n\n### 10.2. Entity representation\nAdded and updated entities are represented in the entity set using their standard representation.\nFrom the perspective of the set, there is no difference between an added or updated entity.\n\nRemoved entities are represented using only their \"id\" and an \"@removed\" node.\nThe presence of an \"@removed\" node MUST represent the removal of the entry from the set.\n\n### 10.3. Obtaining a delta link\nA delta link is obtained by querying a collection or entity and appending a $delta query string parameter.\nFor example:\n\n```http\nGET https://api.contoso.com/v1.0/people?$delta\nHTTP/1.1\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"value\":[\n    { \"id\": \"1\", \"name\": \"Matt\"},\n    { \"id\": \"2\", \"name\": \"Mark\"},\n    { \"id\": \"3\", \"name\": \"John\"}\n  ],\n  \"@deltaLink\": \"{opaqueUrl}\"\n}\n```\n\nNote: If the collection is paginated the deltaLink will only be present on the final page but MUST reflect any changes to the data returned across all pages.\n\n### 10.4. Contents of a delta link response\nAdded/Updated entries MUST appear as regular JSON objects, with regular item properties.\nReturning the added/modified items in their regular representation allows the client to merge them into their existing \"cache\" using standard merge concepts based on the \"id\" field.\n\nEntries removed from the defined collection MUST be included in the response.\nItems removed from the set MUST be represented using only their \"id\" and an \"@removed\" node.\n\n### 10.5. Using a delta link\nThe client requests changes by invoking the GET method on the delta link.\nThe client MUST use the delta URL as is -- in other words the client MUST NOT modify the URL in any way (e.g., parsing it and adding additional query string parameters).\nIn this example:\n\n```http\nGET https://{opaqueUrl} HTTP/1.1\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"value\":[\n    { \"id\": \"1\", \"name\": \"Mat\"},\n    { \"id\": \"2\", \"name\": \"Marc\"},\n    { \"id\": \"3\", \"@removed\": {} },\n    { \"id\": \"4\", \"name\": \"Luc\"}\n  ],\n  \"@deltaLink\": \"{opaqueUrl}\"\n}\n```\n\nThe results of a request against the delta link may span multiple pages but MUST be ordered by the service across all pages in such a way as to ensure a deterministic result when applied in order to the response that contained the delta link.\n\nIf no changes have occurred, the response is an empty collection that contains a delta link for subsequent changes if requested.\nThis delta link MAY be identical to the delta link resulting in the empty collection of changes.\n\nIf the delta link is no longer valid, the service MUST respond with _410 Gone_. The response SHOULD include a Location header that the client can use to retrieve a new baseline set of results.\n\n## 11. JSON standardizations\n### 11.1. JSON formatting standardization for primitive types\nPrimitive values MUST be serialized to JSON following the rules of [RFC8259][rfc-8259].\n\n**Important note for 64bit integers:** JavaScript will silently truncate integers larger than `Number.MAX_SAFE_INTEGER` (2^53-1) or numbers smaller than `Number.MIN_SAFE_INTEGER` (-2^53+1). If the service is expected to return integer values outside the range of safe values, strongly consider returning the value as a string in order to maximize interoperability and avoid data loss.\n\n### 11.2. Guidelines for dates and times\n#### 11.2.1. Producing dates\nServices MUST produce dates using the `DateLiteral` format, and SHOULD use the `Iso8601Literal` format unless there are compelling reasons to do otherwise.\nServices that do use the `StructuredDateLiteral` format MUST NOT produce dates using the `T` kind unless BOTH the additional precision is REQUIRED, and ECMAScript clients are explicitly unsupported.\n(Non-Normative statement: When deciding which particular `DateKind` to standardize on, the approximate order of preference is `E, C, U, W, O, X, I, T`.\nThis optimizes for ECMAScript, .NET, and C++ programmers, in that order.)\n\n#### 11.2.2. Consuming dates\nServices MUST accept dates from clients that use the same `DateLiteral` format (including the `DateKind`, if applicable) that they produce, and SHOULD accept dates using any `DateLiteral` format.\n\n#### 11.2.3. Compatibility\nServices MUST use the same `DateLiteral` format (including the same `DateKind`, if applicable) for all resources of the same type, and SHOULD use the same `DateLiteral` format (and `DateKind`, if applicable) for all resources across the entire service.\n\nAny change to the `DateLiteral` format produced by the service (including the `DateKind`, if applicable) and any reductions in the `DateLiteral` formats (and `DateKind`, if applicable) accepted by the service MUST be treated as a breaking change.\nAny widening of the `DateLiteral` formats accepted by the service is NOT considered a breaking change.\n\n### 11.3. JSON serialization of dates and times\nRound-tripping serialized dates with JSON is a hard problem.\nAlthough ECMAScript supports literals for most built-in types, it does not define a literal format for dates.\nThe Web has coalesced around the [ECMAScript subset of ISO 8601 date formats (ISO 8601)][iso-8601], but there are situations where this format is not desirable.\nFor those cases, this document defines a JSON serialization format that can be used to unambiguously represent dates in different formats.\nOther serialization formats (such as XML) could be derived from this format.\n\n#### 11.3.1. The `DateLiteral` format\nDates represented in JSON are serialized using the following grammar.\nInformally, a `DateValue` is either an ISO 8601-formatted string or a JSON object containing two properties named `kind` and `value` that together define a point in time.\nThe following is not a context-free grammar; in particular, the interpretation of `DateValue` depends on the value of `DateKind`, but this minimizes the number of productions required to describe the format.\n\n```\nDateLiteral:\n  Iso8601Literal\n  StructuredDateLiteral\n\nIso8601Literal:\n  A string literal as defined in https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15. Note that the full grammar for ISO 8601 (such as \"basic format\" without separators) is not supported.\n  All dates default to UTC unless specified otherwise.\n\nStructuredDateLiteral:\n  { DateKindProperty , DateValueProperty }\n  { DateValueProperty , DateKindProperty }\n\nDateKindProperty\n  \"kind\" : DateKind\n\nDateKind:\n  \"C\"            ; see below\n  \"E\"            ; see below\n  \"I\"            ; see below\n  \"O\"            ; see below\n  \"T\"            ; see below\n  \"U\"            ; see below\n  \"W\"            ; see below\n  \"X\"            ; see below\n\nDateValueProperty:\n  \"value\" : DateValue\n\nDateValue:\n  UnsignedInteger        ; not defined here\n  SignedInteger        ; not defined here\n  RealNumber        ; not defined here\n  Iso8601Literal        ; as above\n```\n\n#### 11.3.2. Commentary on date formatting\nA `DateLiteral` using the `Iso8601Literal` production is relatively straightforward.\nHere is an example of an object with a property named `creationDate` that is set to February 13, 2015, at 1:15 p.m. UTC:\n\n```json\n{ \"creationDate\" : \"2015-02-13T13:15Z\" }\n```\n\nThe `StructuredDateLiteral` consists of a `DateKind` and an accompanying `DateValue` whose valid values (and their interpretation) depend on the `DateKind`. The following table describes the valid combinations and their meaning:\n\nDateKind | DateValue       | Colloquial Name & Interpretation                                                                                                                  | More Info\n-------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------\nC        | UnsignedInteger | \"CLR\"; number of milliseconds since midnight January 1, 0001; negative values are not allowed. *See note below.*                                  | [MSDN][clr-time]\nE        | SignedInteger   | \"ECMAScript\"; number of milliseconds since midnight, January 1, 1970.                                                                             | [ECMA International][ecmascript-time]\nI        | Iso8601Literal  | \"ISO 8601\"; a string limited to the ECMAScript subset.                                                                                            |\nO        | RealNumber      | \"OLE Date\"; integral part is the number of days since midnight, December 31, 1899, and fractional part is the time within the day (0.5 = midday). | [MSDN][ole-date]\nT        | SignedInteger   | \"Ticks\"; number of ticks (100-nanosecond intervals) since midnight January 1, 1601. *See note below.*                                             | [MSDN][ticks-time]\nU        | SignedInteger   | \"UNIX\"; number of seconds since midnight, January 1, 1970.                                                                                        | [MSDN][unix-time]\nW        | SignedInteger   | \"Windows\"; number of milliseconds since midnight January 1, 1601. *See note below.*                                                               | [MSDN][windows-time]\nX        | RealNumber      | \"Excel\"; as for `O` but the year 1900 is incorrectly treated as a leap year, and day 0 is \"January 0 (zero)\".                                     | [Microsoft Support][excel-time]\n\n**Important note for `C` and `W` kinds:** The native CLR and Windows times are represented by 100-nanosecond \"tick\" values.\nTo interoperate with ECMAScript clients that have limited precision, _these values MUST be converted to and from milliseconds_ when (de)serialized as a `DateLiteral`.\nOne millisecond is equivalent to 10,000 ticks.\n\n**Important note for `T` kind:** This kind preserves the full fidelity of the Windows native time formats (and is trivially convertible to and from the native CLR format) but is incompatible with ECMAScript clients.\nTherefore, its use SHOULD be limited to only those scenarios that both require the additional precision and do not need to interoperate with ECMAScript clients.\n\nHere is the same example of an object with a property named creationDate that is set to February 13, 2015, at 1:15 p.m. UTC, using several formats:\n\n```json\n[\n  { \"creationDate\" : { \"kind\" : \"O\", \"value\" : 42048.55 } },\n  { \"creationDate\" : { \"kind\" : \"E\", \"value\" : 1423862100000 } }\n]\n```\n\nOne of the benefits of separating the kind from the value is that once a client knows the kind used by a particular service, it can interpret the value without requiring any additional parsing.\nIn the common case of the value being a number, this makes coding easier for developers:\n\n```csharp\n// We know this service always gives out ECMAScript-format dates\nvar date = new Date(serverResponse.someObject.creationDate.value);\n```\n\n### 11.4. Durations\n[Durations][wikipedia-iso8601-durations] need to be serialized in conformance with [ISO 8601][wikipedia-iso8601-durations].\nDurations are \"represented by the format `P[n]Y[n]M[n]DT[n]H[n]M[n]S`.\"\nFrom the standard:\n- P is the duration designator (historically called \"period\") placed at the start of the duration representation.\n- Y is the year designator that follows the value for the number of years.\n- M is the month designator that follows the value for the number of months.\n- W is the week designator that follows the value for the number of weeks.\n- D is the day designator that follows the value for the number of days.\n- T is the time designator that precedes the time components of the representation.\n- H is the hour designator that follows the value for the number of hours.\n- M is the minute designator that follows the value for the number of minutes.\n- S is the second designator that follows the value for the number of seconds.\n\nFor example, \"P3Y6M4DT12H30M5S\" represents a duration of \"three years, six months, four days, twelve hours, thirty minutes, and five seconds.\"\n\n### 11.5. Intervals\n[Intervals][wikipedia-iso8601-intervals] are defined as part of [ISO 8601][wikipedia-iso8601-intervals].\n- Start and end, such as \"2007-03-01T13:00:00Z/2008-05-11T15:30:00Z\"\n- Start and duration, such as \"2007-03-01T13:00:00Z/P1Y2M10DT2H30M\"\n- Duration and end, such as \"P1Y2M10DT2H30M/2008-05-11T15:30:00Z\"\n- Duration only, such as \"P1Y2M10DT2H30M\", with additional context information\n\n### 11.6. Repeating intervals\n[Repeating Intervals][wikipedia-iso8601-repeatingintervals], as per [ISO 8601][wikipedia-iso8601-repeatingintervals], are:\n\n> Formed by adding \"R[n]/\" to the beginning of an interval expression, where R is used as the letter itself and [n] is replaced by the number of repetitions.\nLeaving out the value for [n] means an unbounded number of repetitions.\n\nFor example, to repeat the interval of \"P1Y2M10DT2H30M\" five times starting at \"2008-03-01T13:00:00Z\", use \"R5/2008-03-01T13:00:00Z/P1Y2M10DT2H30M.\"\n\n## 12. Versioning\n**All APIs compliant with the Microsoft REST API Guidelines MUST support explicit versioning.** It's critical that clients can count on services to be stable over time, and it's critical that services can add features and make changes.\n\n### 12.1. Versioning formats\nServices are versioned using a Major.Minor versioning scheme.\nServices MAY opt for a \"Major\" only version scheme in which case the \".0\" is implied and all other rules in this section apply.\nTwo options for specifying the version of a REST API request are supported:\n- Embedded in the path of the request URL, at the end of the service root: `https://api.contoso.com/v1.0/products/users`\n- As a query string parameter of the URL: `https://api.contoso.com/products/users?api-version=1.0`\n\nGuidance for choosing between the two options is as follows:\n\n1. Services co-located behind a DNS endpoint MUST use the same versioning mechanism.\n2. In this scenario, a consistent user experience across the endpoint is paramount. The Microsoft REST API Guidelines Working Group recommends that new top-level DNS endpoints are not created without explicit conversations with your organization's leadership team.\n3. Services that guarantee the stability of their REST API's URL paths, even through future versions of the API, MAY adopt the query string parameter mechanism. This means the naming and structure of the relationships described in the API cannot evolve after the API ships, even across versions with breaking changes.\n4. Services that cannot ensure URL path stability across future versions MUST embed the version in the URL path.\n\nCertain bedrock services such as Microsoft's Azure Active Directory may be exposed behind multiple endpoints.\nSuch services MUST support the versioning mechanisms of each endpoint, even if that means supporting multiple versioning mechanisms.\n\n#### 12.1.1. Group versioning\nGroup versioning is an OPTIONAL feature that MAY be offered on services using the query string parameter mechanism.\nGroup versions allow for logical grouping of API endpoints under a common versioning moniker.\nThis allows developers to look up a single version number and use it across multiple endpoints.\nGroup version numbers are well known, and services SHOULD reject any unrecognized values.\n\nInternally, services will take a Group Version and map it to the appropriate Major.Minor version.\n\nThe Group Version format is defined as YYYY-MM-DD, for example 2012-12-07 for December 7, 2012. This Date versioning format applies only to Group Versions and SHOULD NOT be used as an alternative to Major.Minor versioning.\n\n##### Examples of group versioning\n\n| Group      | Major.Minor |\n|:-----------|:------------|\n| 2012-12-01 | 1.0         |\n|            | 1.1         |\n|            | 1.2         |\n| 2013-03-21 | 1.0         |\n|            | 2.0         |\n|            | 3.0         |\n|            | 3.1         |\n|            | 3.2         |\n|            | 3.3         |\n\nVersion Format                | Example                | Interpretation\n----------------------------- | ---------------------- | ------------------------------------------\n{groupVersion}                | 2013-03-21, 2012-12-01 | 3.3, 1.2\n{majorVersion}                | 3                      | 3.0\n{majorVersion}.{minorVersion} | 1.2                    | 1.2\n\nClients can specify either the group version or the Major.Minor version:\n\nFor example:\n\n```http\nGET http://api.contoso.com/acct1/c1/blob2?api-version=1.0\n```\n\n```http\nPUT http://api.contoso.com/acct1/c1/b2?api-version=2011-12-07\n```\n\n### 12.2. When to version\nServices MUST increment their version number in response to any breaking API change.\nSee the following section for a detailed discussion of what constitutes a breaking change.\nServices MAY increment their version number for nonbreaking changes as well, if desired.\n\nUse a new major version number to signal that support for existing clients will be deprecated in the future.\nWhen introducing a new major version, services MUST provide a clear upgrade path for existing clients and develop a plan for deprecation that is consistent with their business group's policies.\nServices SHOULD use a new minor version number for all other changes.\n\nOnline documentation of versioned services MUST indicate the current support status of each previous API version and provide a path to the latest version.\n\n### 12.3. Definition of a breaking change\nChanges to the contract of an API are considered a breaking change.\nChanges that impact the backwards compatibility of an API are a breaking change.\n\nTeams MAY define backwards compatibility as their business needs require.\nFor example, Azure defines the addition of a new JSON field in a response to be not backwards compatible.\nOffice 365 has a looser definition of backwards compatibility and allows JSON fields to be added to responses.\n\nClear examples of breaking changes:\n\n1. Removing or renaming APIs or API parameters\n2. Changes in behavior for an existing API\n3. Changes in Error Codes and Fault Contracts\n4. Anything that would violate the [Principle of Least Astonishment][principle-of-least-astonishment]\n\nServices MUST explicitly define their definition of a breaking change, especially with regard to adding new fields to JSON responses and adding new API arguments with default fields.\nServices that are co-located behind a DNS Endpoint with other services MUST be consistent in defining contract extensibility.\n\nThe applicable changes described [in this section of the OData V4 spec][odata-breaking-changes] SHOULD be considered part of the minimum bar that all services MUST consider a breaking change.\n\n## 13. Long running operations\nLong running operations, sometimes called async operations, tend to mean different things to different people.\nThis section sets forth guidance around different types of long running operations, and describes the wire protocols and best practices for these types of operations.\n\n1. One or more clients MUST be able to monitor and operate on the same resource at the same time.\n2. The state of the system SHOULD be discoverable and testable at all times. Clients SHOULD be able to determine the system state even if the operation tracking resource is no longer active. The act of querying the state of a long running operation should itself leverage principles of the web. i.e. well-defined resources with uniform interface semantics. Clients MAY issue a GET on some resource to determine the state of a long running operation\n3. Long running operations SHOULD work for clients looking to \"Fire and Forget\" and for clients looking to actively monitor and act upon results.\n4. Cancellation does not explicitly mean rollback. On a per-API defined case it may mean rollback, or compensation, or completion, or partial completion, etc. Following a cancelled operation, It SHOULD NOT be a client's responsibility to return the service to a consistent state which allows continued service.\n\n### 13.1. Resource based long running operations (RELO)\nResource based modeling is where the status of an operation is encoded in the resource and the wire protocol used is the standard synchronous protocol.\nIn this model state transitions are well defined and goal states are similarly defined.\n\n_This is the preferred model for long running operations and should be used wherever possible._ Avoiding the complexity and mechanics of the LRO Wire Protocol makes things simpler for our users and tooling chain.\n\nAn example may be a machine reboot, where the operation itself completes synchronously but the GET operation on the virtual machine resource would have a \"state: Rebooting\", \"state: Running\" that could be queried at any time.\n\nThis model MAY integrate Push Notifications.\n\nWhile most operations are likely to be POST semantics, in addition to POST semantics, services MAY support PUT semantics via routing to simplify their APIs.\nFor example, a user that wants to create a database named \"db1\" could call:\n\n```http\nPUT https://api.contoso.com/v1.0/databases/db1\n```\n\nIn this scenario the databases segment is processing the PUT operation.\n\nServices MAY also use the hybrid defined below.\n\n### 13.2. Stepwise long running operations\nA stepwise operation is one that takes a long, and often unpredictable, length of time to complete, and doesn't offer state transition modeled in the resource.\nThis section outlines the approach that services should use to expose such long running operations.\n\nService MAY expose stepwise operations.\n\n> Stepwise Long Running Operations are sometimes called \"Async\" operations.\nThis causes confusion, as it mixes elements of platforms (\"Async / await\", \"promises\", \"futures\") with elements of API operation.\nThis document uses the term \"Stepwise Long Running Operation\" or often just \"Stepwise Operation\" to avoid confusion over the word \"Async\".\n\nServices MUST perform as much synchronous validation as practical on stepwise requests.\nServices MUST prioritize returning errors in a synchronous way, with the goal of having only \"Valid\" operations processed using the long running operation wire protocol.\n\nFor an API that's defined as a Stepwise Long Running Operation the service MUST go through the Stepwise Long Running Operation flow even if the operation can be completed immediately.\nIn other words, APIs must adopt and stick with an LRO pattern and not change patterns based on circumstance.\n\n#### 13.2.1. PUT\nServices MAY enable PUT requests for entity creation.\n\n```http\nPUT https://api.contoso.com/v1.0/databases/db1\n```\n\nIn this scenario the _databases_ segment is processing the PUT operation.\n\n```http\nHTTP/1.1 202 Accepted\nOperation-Location: https://api.contoso.com/v1.0/operations/123\n```\n\nFor services that need to return a 201 Created here, use the hybrid flow described below.\n\nThe 202 Accepted should return no body.\nThe 201 Created case should return the body of the target resource.\n\n#### 13.2.2. POST\nServices MAY enable POST requests for entity creation.\n\n```http\nPOST https://api.contoso.com/v1.0/databases/\n\n{\n  \"fileName\": \"someFile.db\",\n  \"color\": \"red\"\n}\n```\n\n```http\nHTTP/1.1 202 Accepted\nOperation-Location: https://api.contoso.com/v1.0/operations/123\n```\n\n#### 13.2.3. POST, hybrid model\nServices MAY respond synchronously to POST requests to collections that create a resource even if the resources aren't fully created when the response is generated.\nIn order to use this pattern, the response MUST include a representation of the incomplete resource and an indication that it is incomplete.\n\nFor example:\n\n```http\nPOST https://api.contoso.com/v1.0/databases/ HTTP/1.1\nHost: api.contoso.com\nContent-Type: application/json\nAccept: application/json\n\n{\n  \"fileName\": \"someFile.db\",\n  \"color\": \"red\"\n}\n```\n\nService response says the database has been created, but indicates the request is not completed by including the Operation-Location header.\nIn this case the status property in the response payload also indicates the operation has not fully completed.\n\n```http\nHTTP/1.1 201 Created\nLocation: https://api.contoso.com/v1.0/databases/db1\nOperation-Location: https://api.contoso.com/v1.0/operations/123\n\n{\n  \"databaseName\": \"db1\",\n  \"color\": \"red\",\n  \"Status\": \"Provisioning\",\n  [ … other fields for \"database\" …]\n}\n```\n\n#### 13.2.4. Operations resource\nServices MAY provide a \"/operations\" resource at the tenant level.\n\nServices that provide the \"/operations\" resource MUST provide GET semantics.\nGET MUST enumerate the set of operations, following standard pagination, sorting, and filtering semantics.\nThe default sort order for this operation MUST be:\n\nPrimary Sort           | Secondary Sort\n---------------------- | -----------------------\nNot Started Operations | Operation Creation Time\nRunning Operations     | Operation Creation Time\nCompleted Operations   | Operation Creation Time\n\nNote that \"Completed Operations\" is a goal state (see below), and may actually be any of several different states such as \"successful\", \"cancelled\", \"failed\" and so forth.\n\n#### 13.2.5. Operation resource\nAn operation is a user addressable resource that tracks a stepwise long running operation.\nOperations MUST support GET semantics.\nThe GET operation against an operation MUST return:\n\n1. The operation resource, it's state, and any extended state relevant to the particular API.\n2. 200 OK as the response code.\n\nServices MAY support operation cancellation by exposing DELETE on the operation.\nIf supported DELETE operations MUST be idempotent.\n\n> Note: From an API design perspective, cancellation does not explicitly mean rollback.\nOn a per-API defined case it may mean rollback, or compensation, or completion, or partial completion, etc.\nFollowing a cancelled operation, It SHOULD NOT be a client's responsibility to return the service to a consistent state which allows continued service.\n\nServices that do not support operation cancellation MUST return a 405 Method Not Allowed in the event of a DELETE.\n\nOperations MUST support the following states:\n\n1. NotStarted\n2. Running\n3. Succeeded. Terminal State.\n4. Failed. Terminal State.\n\nServices MAY add additional states, such as \"Cancelled\" or \"Partially Completed\". Services that support cancellation MUST sufficiently describe their cancellation such that the state of the system can be accurately determined, and any compensating actions may be run.\n\nServices that support additional states should consider this list of canonical names and avoid creating new names if possible: Cancelling, Cancelled, Aborting, Aborted, Tombstone, Deleting, Deleted.\n\nAn operation MUST contain, and provide in the GET response, the following information:\n\n1. The timestamp when the operation was created.\n2. A timestamp for when the current state was entered.\n3. The operation state (notstarted / running / completed).\n\nServices MAY add additional, API specific, fields into the operation.\nThe operation status JSON returned looks like:\n\n```json\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"lastActionDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"status\": \"notstarted | running | succeeded | failed\"\n}\n```\n\n##### Percent complete\nSometimes it is impossible for services to know with any accuracy when an operation will complete.\nWhich makes using the Retry-After header problematic.\nIn that case, services MAY include, in the operationStatus JSON, a percent complete field.\n\n```json\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"percentComplete\": \"50\",\n  \"status\": \"running\"\n}\n```\n\nIn this example the server has indicated to the client that the long running operation is 50% complete.\n\n##### Target resource location\nFor operations that result in, or manipulate, a resource the service MUST include the target resource location in the status upon operation completion.\n\n```json\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"lastActionDateTime\": \"2015-06-19T12-06-03.0024Z\",\n  \"status\": \"succeeded\",\n  \"resourceLocation\": \"https://api.contoso.com/v1.0/databases/db1\"\n}\n```\n\n#### 13.2.6. Operation tombstones\nServices MAY choose to support tombstoned operations.\nServices MAY choose to delete tombstones after a service defined period of time.\n\n#### 13.2.7. The typical flow, polling\n- Client invokes a stepwise operation by invoking an action using POST\n- The server MUST indicate the request has been started by responding with a 202 Accepted status code. The response SHOULD include the location header containing a URL that the client should poll for the results after waiting the number of seconds specified in the Retry-After header.\n- Client polls the location until receiving a 200 response with a terminal operation state.\n\n##### Example of the typical flow, polling\nClient invokes the restart action:\n\n```http\nPOST https://api.contoso.com/v1.0/databases HTTP/1.1\nAccept: application/json\n\n{\n  \"fromFile\": \"myFile.db\",\n  \"color\": \"red\"\n}\n```\n\nThe server response indicates the request has been created.\n\n```http\nHTTP/1.1 202 Accepted\nOperation-Location: https://api.contoso.com/v1.0/operations/123\n```\n\nClient waits for a period of time then invokes another request to try to get the operation status.\n\n```http\nGET https://api.contoso.com/v1.0/operations/123\nAccept: application/json\n```\n\nServer responds that results are still not ready and optionally provides a recommendation to wait 30 seconds.\n\n```http\nHTTP/1.1 200 OK\nRetry-After: 30\n\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.4Z\",\n  \"status\": \"running\"\n}\n```\n\nClient waits the recommended 30 seconds and then invokes another request to get the results of the operation.\n\n```http\nGET https://api.contoso.com/v1.0/operations/123\nAccept: application/json\n```\n\nServer responds with a \"status:succeeded\" operation that includes the resource location.\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"lastActionDateTime\": \"2015-06-19T12-06-03.0024Z\",\n  \"status\": \"succeeded\",\n  \"resourceLocation\": \"https://api.contoso.com/v1.0/databases/db1\"\n}\n```\n\n#### 13.2.8. The typical flow, push notifications\n1. Client invokes a long running operation by invoking an action using POST. The client has a push notification already setup on the parent resource.\n2. The service indicates the request has been started by responding with a 202 Accepted status code. The client ignores everything else.\n3. Upon completion of the overall operation the service pushes a notification via the subscription on the parent resource.\n4. The client retrieves the operation result via the resource URL.\n\n##### Example of the typical flow, push notifications existing subscription\nClient invokes the backup action.\nThe client already has a push notification subscription setup for db1.\n\n```http\nPOST https://api.contoso.com/v1.0/databases/db1?backup HTTP/1.1\nAccept: application/json\n```\n\nThe server response indicates the request has been accepted.\n\n```http\nHTTP/1.1 202 Accepted\nOperation-Location: https://api.contoso.com/v1.0/operations/123\n```\n\nThe caller ignores all the headers in the return.\n\nThe target URL receives a push notification when the operation is complete.\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"value\": [\n    {\n      \"subscriptionId\": \"1234-5678-1111-2222\",\n      \"context\": \"subscription context that was specified at setup\",\n      \"resourceUrl\": \"https://api.contoso.com/v1.0/databases/db1\",\n      \"userId\" : \"contoso.com/user@contoso.com\",\n      \"tenantId\" : \"contoso.com\"\n    }\n  ]\n}\n```\n\n#### 13.2.9. Retry-After\nIn the examples above the Retry-After header indicates the number of seconds that the client should wait before trying to get the result from the URL identified by the location header.\n\nThe HTTP specification allows the Retry-After header to alternatively specify a HTTP date, so clients should be prepared to handle this as well.\n\n```http\nHTTP/1.1 202 Accepted\nOperation-Location: http://api.contoso.com/v1.0/operations/123\nRetry-After: 60\n```\n\nNote: The use of the HTTP Date is inconsistent with the use of ISO 8601 Date Format used throughout this document, but is explicitly defined by the HTTP standard in [RFC 7231][rfc-7231-7-1-1-1]. Services SHOULD prefer the integer number of seconds (in decimal) format over the HTTP date format.\n\n### 13.3. Retention policy for operation results\nIn some situations, the result of a long running operation is not a resource that can be addressed.\nFor example, if you invoke a long running Action that returns a Boolean (rather than a resource).\nIn these situations, the Location header points to a place where the Boolean result can be retrieved.\n\nWhich begs the question: \"How long should operation results be retained?\"\n\nA recommended minimum retention time is 24 hours.\n\nOperations SHOULD transition to \"tombstone\" for an additional period of time prior to being purged from the system.\n\n## 14. Throttling, Quotas, and Limits\n### 14.1. Principles\nServices should be as responsive as possible, so as not to block callers.\nAs a rule of thumb any API call that is expected to take longer than 0.5 seconds in the 99th percentile, should consider using the Long-running Operations pattern for those calls.\nObviously, services cannot guarantee these response times in the face of potentially unlimited load from callers. Services should therefore design and document call request limits for clients, and respond with appropriate, actionable errors and error messages if these limits are exceeded.\nServices should respond quickly with an error when they are generally overloaded, rather than simply respond slowly.\nFinally, many services will have quotas on calls, perhaps a number of operations per hour or day, usually related to a service plan or price.\nWhen these quotas are exceeded services must also provide immediate, actionable errors.\nQuotas and Limits should be scoped to a customer unit: a subscription, a tenant, an application, a plan, or without any other identification a range of ip addresses…as appropriate to the service goals so that the load is properly shared and one unit is not interfering with another.\n\n### 14.2. Return Codes (429 vs 503)\nHTTP specifies two return codes for these scenarios: '429 Too Many Requests' and '503 Service Unavailable'.\nServices should use 429 for cases where clients are making too many calls and can fix the situation by changing their call pattern.\nServices should respond with 503 in cases where general load or other problems outside the control of the individual callers is responsible for the service becoming slow.\nIn all cases, services should also provide information suggesting how long the callers should wait before trying in again.\nClients should respect these headers and also implement other transient fault handling techniques.\nHowever, there may be clients that simply retry immediately upon failure, potentially increasing the load on the service.\nTo handle this, services should design so that returning 429 or 503 is as inexpensive as possible, either by putting in special fastpath code, or ideally by depending on a common frontdoor or load balancer that provides this functionality.\n\n### 14.3. Retry-After and RateLimit Headers\nThe Retry-After header is the standard way for responding to clients who are being throttled.\nIt is also common, but optional, in the case of limits and quotas (but not overall system load) to respond with header describing the limit that was exceeded.\nHowever, services across Microsoft and the industry use a wide range of different headers for this purpose.\nWe recommend using three headers to describe the limit, the number of calls remaining under the limit, and the time when the limit will reset.\nHowever, other headers may be appropriate for specific types of limits. In all cases these must be documented.\n\n### 14.4. Service Guidance\nServices should choose time windows as appropriate for the SLAs or business objectives.\nIn the case of Quotas, the Retry-After time and time window may be very long (hours, days, weeks, even months. Services use 429 to indicate the specific caller has made too many calls, and 503 to indicate that the service is load shedding but that it is not the caller’s responsibility.\n\n#### 14.4.1. Responsiveness\n1. Services MUST respond quickly in all circumstances, even when under load.\n2. Calls that take longer than 1s to respond in the 99th percentile SHOULD use the Long-Running Operation pattern\n3. Calls that take longer than 0.5s to respond in the 99th percentile should strongly consider the LRO pattern\n4. Services SHOULD NOT introduce sleeps, pauses, etc. that block callers or are not actionable (“tar-pitting”).\n\n#### 14.4.2. Rate Limits and Quotas\nWhen a caller has made too many calls\n\n1. Services MUST return a 429 code\n2. Services MUST return a standard error response describing the specifics so that a programmer can make appropriate changes\n3. Services MUST return a Retry-After header that indicates how long clients should wait before retrying\n4. Services MAY return RateLimit headers that document the limit or quota that has been exceeded\n5. Services MAY return RateLimit-Limit: the number of calls the client is allowed to make in a time window\n6. Services MAY return RateLimit-Remaining: the number of calls remaining in the time window\n7. Services MAY return RateLimit-Reset: the time at which the window resets in UTC epoch seconds\n8. Services MAY return other service specific RateLimit headers as appropriate for more detailed information or specific limits or quotas\n\n#### 14.4.3. Overloaded services\nWhen services are generally overloaded and  load shedding\n\n1. Services MUST Return a 503 code\n2. Services MUST Return a standard error response (see 7.10.2) describing the specifics so that a programmer can make appropriate changes\n3. Services MUST Return a Retry-After header that indicates how long clients should wait before retrying\n4. In the 503 case, the service SHOULD NOT return RateLimit headers\n\n#### 14.4.4. Example Response\n\n```http\nHTTP/1.1 429 Too Many Requests\nContent-Type: application/json\nRetry-After: 5\nRateLimit-Limit: 1000\nRateLimit-Remaining: 0\nRateLimit-Reset: 1538152773\n{\n  \"error\": {\n    \"code\": \"requestLimitExceeded\",\n    \"message\": \"The caller has made too many requests in the time period.\",\n    \"details\": {\n      \"code\": \"RateLimit\",\n       \"limit\": \"1000\",\n       \"remaining\": \"0\",\n       \"reset\": \"1538152773\",\n      }\n    }\n}\n```\n\n### 14.5. Caller Guidance\nCallers include all users of the API: tools, portals, other services, not just user clients\n\n1. Callers MUST wait for a minimum of time indicated in a response with a Retry-After before retrying a request.\n2. Callers MAY assume that request is retriable after receiving a response with a Retry-After header without making any changes to the request.\n3. Clients SHOULD use shared SDKs and common transient fault libraries to implement the proper behavior\n\nSee: https://docs.microsoft.com/en-us/azure/architecture/best-practices/transient-faults\n\n### 14.6. Handling callers that ignore Retry-After headers\nIdeally, 429 and 503 returns are so low cost that even clients that retry immediately can be handled.\nIn these cases, if possible the service team should make an effort to contact or fix the client.\nIf it is a known partner, a bug or incident should be filed.\nIn extreme cases it may be necessary to use DoS style protections such as blocking the caller.\n\n## 15. Push notifications via webhooks\n### 15.1. Scope\nServices MAY implement push notifications via web hooks.\nThis section addresses the following key scenario:\n\n> Push notification via HTTP Callbacks, often called Web Hooks, to publicly-addressable servers.\n\nThe approach set forth is chosen due to its simplicity, broad applicability, and low barrier to entry for service subscribers.\nIt's intended as a minimal set of requirements and as a starting point for additional functionality.\n\n### 15.2. Principles\nThe core principles for services that support web hooks are:\n\n1. Services MUST implement at least a poke/pull model. In the poke/pull model, a notification is sent to a client, and clients then send a request to get the current state or the record of change since their last notification. This approach avoids complexities around message ordering, missed messages, and change sets.  Services MAY add more data to provide rich notifications.\n2. Services MUST implement the challenge/response protocol for configuring callback URLs.\n3. Services SHOULD have a recommended age-out period, with flexibility for services to vary based on scenario.\n4. Services SHOULD allow subscriptions that are raising successful notifications to live forever and SHOULD be tolerant of reasonable outage periods.\n5. Firehose subscriptions MUST be delivered only over HTTPS. Services SHOULD require other subscription types to be HTTPS. See the \"Security\" section for more details.\n\n### 15.3. Types of subscriptions\nThere are two subscription types, and services MAY implement either, both, or none.\nThe supported subscription types are:\n\n1. Firehose subscriptions – a subscription is manually created for the subscribing application, typically in an app registration portal.  Notifications of activity that any users have consented to the app receiving are sent to this single subscription.\n2. Per-resource subscriptions – the subscribing application uses code to programmatically create a subscription at runtime for some user-specific entity(s).\n\nServices that support both subscription types SHOULD provide differentiated developer experiences for the two types:\n\n1. Firehose – Services MUST NOT require developers to create code except to directly verify and respond to notifications.  Services MUST provide administrative UI for subscription management.  Services SHOULD NOT assume that end users are aware of the subscription, only the subscribing application's functionality.\n2. Per-user – Services MUST provide an API for developers to create and manage subscriptions as part of their app as well as verifying and responding to notifications.  Services MAY expect end users to be aware of subscriptions and MUST allow end users to revoke subscriptions where they were created directly in response to user actions.\n\n### 15.4. Call sequences\nThe call sequence for a firehose subscription MUST follow the diagram below.\nIt shows manual registration of application and subscription, and then the end user making use of one of the service's APIs.\nAt this part of the flow, two things MUST be stored:\n\n1. The service MUST store the end user's act of consent to receiving notifications from this specific application (typically a background usage OAUTH scope.)\n2. The subscribing application MUST store the end user's tokens in order to call back for details once notified of changes.\n\nThe final part of the sequence is the notification flow itself.\n\nNon-normative implementation guidance:  A resource in the service changes and the service needs to run the following logic:\n\n1. Determine the set of users who have access to the resource, and could thus expect apps to receive notifications about it on their behalf.\n2. See which of those users have consented to receiving notifications and from which apps.\n3. See which apps have registered a firehose subscription.\n4. Join 1, 2, 3 to produce the concrete set of notifications that must be sent to apps.\n\nIt should be noted that the act of user consent and the act of setting up a firehose subscription could arrive in either order.\nServices SHOULD send notifications with setup processed in either order.\n\n![Firehose subscription setup][websequencediagram-firehose-subscription-setup]\n\nFor a per-user subscription, app registration is either manual or automated.\nThe call flow for a per-user subscription MUST follow the diagram below.\nIt shows the end user making use of one of the service's APIs, and again, the same two things MUST be stored:\n\n1. The service MUST store the end user's act of consent to receiving notifications from this specific application (typically a background usage OAUTH scope).\n2. The subscribing application MUST store the end user's tokens in order to call back for details once notified of changes.\n\nIn this case, the subscription is set up programmatically using the end-user's token from the subscribing application.\nThe app MUST store the ID of the registered subscription alongside the user tokens.\n\nNon normative implementation guidance: In the final part of the sequence, when an item of data in the service changes and the service needs to run the following logic:\n\n1. Find the set of subscriptions that correspond via resource to the data that changed.\n2. For subscriptions created under an app+user token, send a notification to the app per subscription with the subscription ID and user id of the subscription-creator.\n- For subscriptions created with an app only token, check that the owner of the changed data or any user that has visibility of the changed data has consented to notifications to the application, and if so send a set of notifications per user id to the app per subscription with the subscription ID.\n\n  ![User subscription setup][websequencediagram-user-subscription-setup]\n\n### 15.5. Verifying subscriptions\nWhen subscriptions change either programmatically or in response to change via administrative UI portals, the subscribing service needs to be protected from malicious or unexpected calls from services pushing potentially large volumes of notification traffic.\n\nFor all subscriptions, whether firehose or per-user, services MUST send a verification request as part of creation or modification via portal UI or API request, before sending any other notifications.\n\nVerification requests MUST be of the following format as an HTTP/HTTPS POST to the subscription's _notificationUrl_.\n\n```http\nPOST https://{notificationUrl}?validationToken={randomString}\nClientState: clientOriginatedOpaqueToken (if provided by client on subscription-creation)\nContent-Length: 0\n```\n\nFor the subscription to be set up, the application MUST respond with 200 OK to this request, with the _validationToken_ value as the sole entity body.\nNote that if the _notificationUrl_ contains query parameters, the _validationToken_ parameter must be appended with an `&`.\n\nIf any challenge request does not receive the prescribed response within 5 seconds of sending the request, the service MUST return an error, MUST NOT create the subscription, and MUST NOT send further requests or notifications to _notificationUrl_.\n\nServices MAY perform additional validations on URL ownership.\n\n### 15.6. Receiving notifications\nServices SHOULD send notifications in response to service data changes that do not include details of the changes themselves, but include enough information for the subscribing application to respond appropriately to the following process:\n\n1. Applications MUST identify the correct cached OAuth token to use for a callback\n2. Applications MAY look up any previous delta token for the relevant scope of change\n3. Applications MUST determine the URL to call to perform the relevant query for the new state of the service, which MAY be a delta query.\n\nServices that are providing notifications that will be relayed to end users MAY choose to add more detail to notification packets in order to reduce incoming call load on their service.\n Such services MUST be clear that notifications are not guaranteed to be delivered and may be lossy or out of order.\n\nNotifications MAY be aggregated and sent in batches.\nApplications MUST be prepared to receive multiple events inside a single push notification.\n\nThe service MUST send all Web Hook data notifications as POST requests.\n\nServices MUST allow for a 30-second timeout for notifications.\nIf a timeout occurs or the application responds with a 5xx response, then the service SHOULD retry the notification with exponential back-off.\nAll other responses will be ignored.\n\nThe service MUST NOT follow 301/302 redirect requests.\n\n#### 15.6.1. Notification payload\nThe basic format for notification payloads is a list of events, each containing the id of the subscription whose referenced resources have changed, the type of change, the resource that should be consumed to identify the exact details of the change and sufficient identity information to look up the token required to call that resource.\n\nFor a firehose subscription, a concrete example of this may look like:\n\n```json\n{\n  \"value\": [\n    {\n      \"subscriptionId\": \"32b8cbd6174ab18b\",\n      \"resource\": \"https://api.contoso.com/v1.0/users/user@contoso.com/files?$delta\",\n      \"userId\" : \"<User GUID>\",\n      \"tenantId\" : \"<Tenant Id>\"\n    }\n  ]\n}\n```\n\nFor a per-user subscription, a concrete example of this may look like:\n\n```json\n{\n  \"value\": [\n    {\n      \"subscriptionId\": \"32b8cbd6174ab183\",\n      \"clientState\": \"clientOriginatedOpaqueToken\",\n      \"expirationDateTime\": \"2016-02-04T11:23Z\",\n      \"resource\": \"https://api.contoso.com/v1.0/users/user@contoso.com/files/$delta\",\n      \"userId\" : \"<User GUID>\",\n      \"tenantId\" : \"<Tenant Id>\"\n    },\n    {\n      \"subscriptionId\": \"97b391179fa22\",\n      \"clientState \": \"clientOriginatedOpaqueToken\",\n      \"expirationDateTime\": \"2016-02-04T11:23Z\",\n      \"resource\": \"https://api.contoso.com/v1.0/users/user@contoso.com/files/$delta\",\n      \"userId\" : \"<User GUID>\",\n      \"tenantId\" : \"<Tenant Id>\"\n    }\n  ]\n}\n```\n\nFollowing is a detailed description of the JSON payload.\n\nA notification item consists a top-level object that contains an array of events, each of which identified the subscription due to which this notification is being sent.\n\nField | Description\n----- | --------------------------------------------------------------------------------------------------\nvalue | Array of events that have been raised within the subscription’s scope since the last notification.\n\nEach item of the events array contains the following properties:\n\nField              | Description\n------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\nsubscriptionId     | The id of the subscription due to which this notification has been sent.<br/>Services MUST provide the *subscriptionId* field.\nclientState        | Services MUST provide the *clientState* field if it was provided at subscription creation time.\nexpirationDateTime | Services MUST provide the *expirationDateTime* field if the subscription has one.\nresource           | Services MUST provide the resource field. This URL MUST be considered opaque by the subscribing application.  In the case of a richer notification it MAY be subsumed by message content that implicitly contains the resource URL to avoid duplication.<br/>If a service is providing this data as part of a more detailed data packet, then it need not be duplicated.\nuserId             | Services MUST provide this field for user-scoped resources.  In the case of user-scoped resources, the unique identifier for the user should be used.<br/>In the case of resources shared between a specific set of users, multiple notifications must be sent, passing the unique identifier of each user.<br/>For tenant-scoped resources, the user id of the subscription should be used.\ntenantId           | Services that wish to support cross-tenant requests SHOULD provide this field. Services that provide notifications on tenant-scoped data MUST send this field.\n\n### 15.7. Managing subscriptions programmatically\nFor per-user subscriptions, an API MUST be provided to create and manage subscriptions.\nThe API must support at least the operations described here.\n\n#### 15.7.1. Creating subscriptions\nA client creates a subscription by issuing a POST request against the subscriptions resource.\nThe subscription namespace is client-defined via the POST operation.\n\n```\nhttps://api.contoso.com/apiVersion/$subscriptions\n```\n\nThe POST request contains a single subscription object to be created.\nThat subscription object has the following properties:\n\nProperty Name   | Required | Notes\n--------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------\nresource        | Yes      | Resource path to watch.\nnotificationUrl | Yes      | The target web hook URL.\nclientState     | No       | Opaque string passed back to the client on all notifications. Callers may choose to use this to provide tagging mechanisms.\n\nIf the subscription was successfully created, the service MUST respond with the status code 201 CREATED and a body containing at least the following properties:\n\nProperty Name      | Required | Notes\n------------------ | -------- | -------------------------------------------------------------------------------------------\nid                 | Yes      | Unique ID of the new subscription that can be used later to update/delete the subscription.\nexpirationDateTime | No       | Uses existing Microsoft REST API Guidelines defined time formats.\n\nCreation of subscriptions SHOULD be idempotent.\nThe combination of properties scoped to the auth token, provides a uniqueness constraint.\n\nBelow is an example request using a User + Application principal to subscribe to notifications from a file:\n\n```http\nPOST https://api.contoso.com/files/v1.0/$subscriptions HTTP 1.1\nAuthorization: Bearer {UserPrincipalBearerToken}\n\n{\n  \"resource\": \"http://api.service.com/v1.0/files/file1.txt\",\n  \"notificationUrl\": \"https://contoso.com/myCallbacks\",\n  \"clientState\": \"clientOriginatedOpaqueToken\"\n}\n```\n\nThe service SHOULD respond to such a message with a response format minimally like this:\n\n```json\n{\n  \"id\": \"32b8cbd6174ab18b\",\n  \"expirationDateTime\": \"2016-02-04T11:23Z\"\n}\n```\n\nBelow is an example using an Application-Only principal where the application is watching all files to which it's authorized:\n\n```http\nPOST https://api.contoso.com/files/v1.0/$subscriptions HTTP 1.1\nAuthorization: Bearer {ApplicationPrincipalBearerToken}\n\n{\n  \"resource\": \"All.Files\",\n  \"notificationUrl\": \"https://contoso.com/myCallbacks\",\n  \"clientState\": \"clientOriginatedOpaqueToken\"\n}\n```\n\nThe service SHOULD respond to such a message with a response format minimally like this:\n\n```json\n{\n  \"id\": \"8cbd6174abb391179\",\n  \"expirationDateTime\": \"2016-02-04T11:23Z\"\n}\n```\n\n#### 15.7.2. Updating subscriptions\nServices MAY support amending subscriptions.\n To update the properties of an existing subscription, clients use PATCH requests providing the ID and the properties that need to change.\nOmitted properties will retain their values.\nTo delete a property, assign a value of JSON null to it.\n\nAs with creation, subscriptions are individually managed.\n\nThe following request changes the notification URL of an existing subscription:\n\n```http\nPATCH https://api.contoso.com/files/v1.0/$subscriptions/{id} HTTP 1.1\nAuthorization: Bearer {UserPrincipalBearerToken}\n\n{\n  \"notificationUrl\": \"https://contoso.com/myNewCallback\"\n}\n```\n\nIf the PATCH request contains a new _notificationUrl_, the server MUST perform validation on it as described above.\nIf the new URL fails to validate, the service MUST fail the PATCH request and leave the subscription in its previous state.\n\nThe service MUST return an empty body and `204 No Content` to indicate a successful patch.\n\nThe service MUST return an error body and status code if the patch failed.\n\nThe operation MUST succeed or fail atomically.\n\n#### 15.7.3. Deleting subscriptions\nServices MUST support deleting subscriptions.\nExisting subscriptions can be deleted by making a DELETE request against the subscription resource:\n\n```http\nDELETE https://api.contoso.com/files/v1.0/$subscriptions/{id} HTTP 1.1\nAuthorization: Bearer {UserPrincipalBearerToken}\n```\n\nAs with update, the service MUST return `204 No Content` for a successful delete, or an error body and status code to indicate failure.\n\n#### 15.7.4. Enumerating subscriptions\nTo get a list of active subscriptions, clients issue a GET request against the subscriptions resource using a User + Application or Application-Only bearer token:\n\n```http\nGET https://api.contoso.com/files/v1.0/$subscriptions HTTP 1.1\nAuthorization: Bearer {UserPrincipalBearerToken}\n```\n\nThe service MUST return a format as below using a User + Application principal bearer token:\n\n```json\n{\n  \"value\": [\n    {\n      \"id\": \"32b8cbd6174ab18b\",\n      \"resource\": \" http://api.contoso.com/v1.0/files/file1.txt\",\n      \"notificationUrl\": \"https://contoso.com/myCallbacks\",\n      \"clientState\": \"clientOriginatedOpaqueToken\",\n      \"expirationDateTime\": \"2016-02-04T11:23Z\"\n    }\n  ]\n}\n```\n\nAn example that may be returned using Application-Only principal bearer token:\n\n```json\n{\n  \"value\": [\n    {\n      \"id\": \"6174ab18bfa22\",\n      \"resource\": \"All.Files \",\n      \"notificationUrl\": \"https://contoso.com/myCallbacks\",\n      \"clientState\": \"clientOriginatedOpaqueToken\",\n      \"expirationDateTime\": \"2016-02-04T11:23Z\"\n    }\n  ]\n}\n```\n\n### 15.8. Security\nAll service URLs must be HTTPS (that is, all inbound calls MUST be HTTPS). Services that deal with Web Hooks MUST accept HTTPS.\n\nWe recommend that services that allow client defined Web Hook Callback URLs SHOULD NOT transmit data over HTTP.\nThis is because information can be inadvertently exposed via client, network, server logs and other mechanisms.\n\nHowever, there are scenarios where the above recommendations cannot be followed due to client endpoint or software limitations.\nConsequently, services MAY allow web hook URLs that are HTTP.\n\nFurthermore, services that allow client defined HTTP web hooks callback URLs SHOULD be compliant with privacy policy specified by engineering leadership.\nThis will typically include recommending that clients prefer SSL connections and adhere to special precautions to ensure that logs and other service data collection are properly handled.\n\nFor example, services may not want to require developers to generate certificates to onboard.\nServices might only enable this on test accounts.\n\n## 16. Unsupported requests\nRESTful API clients MAY request functionality that is currently unsupported.\nRESTful APIs MUST respond to valid but unsupported requests consistent with this section.\n\n### 16.1. Essential guidance\nRESTful APIs will often choose to limit functionality that can be performed by clients.\nFor instance, auditing systems allow records to be created but not modified or deleted.\nSimilarly, some APIs will expose collections but require or otherwise limit filtering and ordering criteria, or MAY not support client-driven pagination.\n\n### 16.2. Feature allow list\nIf a service does not support any of the below API features, then an error response MUST be provided if the feature is requested by a caller.\nThe features are:\n- Key Addressing in a collection, such as: `https://api.contoso.com/v1.0/people/user1@contoso.com`\n- Filtering a collection by a property value, such as: `https://api.contoso.com/v1.0/people?$filter=name eq 'david'`\n- Filtering a collection by range, such as: `http://api.contoso.com/v1.0/people?$filter=hireDate ge 2014-01-01 and hireDate le 2014-12-31`\n- Client-driven pagination via $top and $skip, such as: `http://api.contoso.com/v1.0/people?$top=5&$skip=2`\n- Sorting by $orderBy, such as: `https://api.contoso.com/v1.0/people?$orderBy=name desc`\n- Providing $delta tokens, such as: `https://api.contoso.com/v1.0/people?$delta`\n\n#### 16.2.1. Error response\nServices MUST provide an error response if a caller requests an unsupported feature found in the feature allow list.\nThe error response MUST be an HTTP status code from the 4xx series, indicating that the request cannot be fulfilled.\nUnless a more specific error status is appropriate for the given request, services SHOULD return \"400 Bad Request\" and an error payload conforming to the error response guidance provided in the Microsoft REST API Guidelines.\nServices SHOULD include enough detail in the response message for a developer to determine exactly what portion of the request is not supported.\n\nExample:\n\n```http\nGET https://api.contoso.com/v1.0/people?$orderBy=name HTTP/1.1\nAccept: application/json\n```\n\n```http\nHTTP/1.1 400 Bad Request\nContent-Type: application/json\n\n{\n  \"error\": {\n    \"code\": \"ErrorUnsupportedOrderBy\",\n    \"message\": \"Ordering by name is not supported.\"\n  }\n}\n```\n\n## 17. Naming guidelines\n### 17.1. Approach\nNaming policies should aid developers in discovering functionality without having to constantly refer to documentation.\nUse of common patterns and standard conventions greatly aids developers in correctly guessing common property names and meanings.\nServices SHOULD use verbose naming patterns and SHOULD NOT use abbreviations other than acronyms that are the dominant mode of expression in the domain being represented by the API, (e.g. Url).\n\n### 17.2. Casing\n- Acronyms SHOULD follow the casing conventions as though they were regular words (e.g. Url).\n- All identifiers including namespaces, entityTypes, entitySets, properties, actions, functions and enumeration values SHOULD use lowerCamelCase.\n- HTTP headers are the exception and SHOULD use standard HTTP convention of Capitalized-Hyphenated-Terms.\n\n### 17.3. Names to avoid\nCertain names are so overloaded in API domains that they lose all meaning or clash with other common usages in domains that cannot be avoided when using REST APIs, such as OAUTH.\nServices SHOULD NOT use the following names:\n- Context\n- Scope\n- Resource\n\n### 17.4. Forming compound names\n- Services SHOULD avoid using articles such as 'a', 'the', 'of' unless needed to convey meaning.\n\t- e.g. names such as aUser, theAccount, countOfBooks SHOULD NOT be used, rather user, account, bookCount SHOULD be preferred.\n- Services SHOULD add a type to a property name when not doing so would cause ambiguity about how the data is represented or would cause the service not to use a common property name.\n- When adding a type to a property name, services MUST add the type at the end, e.g. createdDateTime.\n\n### 17.5. Identity properties\n- Services MUST use string types for identity properties.\n- For OData services, the service MUST use the OData @id property to represent the canonical identifier of the resource.\n- Services MAY use the simple 'id' property to represent a local or legacy primary key value for a resource.\n- Services SHOULD use the name of the relationship postfixed with 'Id' to represent a foreign key to another resource, e.g. subscriptionId.\n\t- The content of this property SHOULD be the canonical ID of the referenced resource.\n\n### 17.6. Date and time properties\n\n- For properties requiring both date and time, services MUST use the suffix 'DateTime'.\n- For properties requiring only date information without specifying time, services MUST use the suffix 'Date', e.g. birthDate.\n- For properties requiring only time information without specifying date, services MUST use the suffix 'Time', e.g. appointmentStartTime.\n\n### 17.7. Name properties\n- For the overall name of a resource typically shown to users, services MUST use the property name 'displayName'.\n- Services MAY use other common naming properties, e.g. givenName, surname, signInName.\n\n### 17.8. Collections and counts\n- Services MUST name collections as plural nouns or plural noun phrases using correct English.\n- Services MAY use simplified English for nouns that have plurals not in common verbal usage.\n\t- e.g. schemas MAY be used instead of schemata.\n- Services MUST name counts of resources with a noun or noun phrase suffixed with 'Count'.\n\n### 17.9. Common property names\nWhere services have a property, whose data matches the names below, the service MUST use the name from this table.\nThis table will grow as services add terms that will be more commonly used.\nService owners adding such terms SHOULD propose additions to this document.\n\n| |\n|------------- |\n attendees     |\n body          |\n createdDateTime |\n childCount    |\n children      |\n contentUrl    |\n country       |\n createdBy     |\n displayName   |\n errorUrl      |\n eTag          |\n event         |\n expirationDateTime |\n givenName     |\n jobTitle      |\n kind          |\n id            |\n lastModifiedDateTime |\n location      |\n memberOf      |\n message       |\n name          |\n owner         |\n people        |\n person        |\n postalCode    |\n photo         |\n preferredLanguage |\n properties    |\n signInName    |\n surname       |\n tags          |\n userPrincipalName |\n webUrl        |\n\n## 18. Appendix\n### 18.1. Sequence diagram notes\nAll sequence diagrams in this document are generated using the [WebSequenceDiagrams.com](https://www.websequencediagrams.com/). To generate them, paste the text below into the web tool.\n\n#### 18.1.1. Push notifications, per user flow\n\n```\n=== Begin Text ===\nnote over Developer, Automation, App Server:\n     An App Developer like MovieMaker\n     Wants to integrate with primary service like Dropbox\nend note\nnote over DB Portal, DB App Registration, DB Notifications, DB Auth, DB Service: The primary service like Dropbox\nnote over Client: The end users' browser or installed app\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Manual App Registration\n\n\nDeveloper <--> DB Portal : Login into Portal, App Registration UX\nDB Portal -> +DB App Registration: App Name etc.\nnote over DB App Registration: Confirm Portal Access Token\n\nDB App Registration -> -DB Portal: App ID\nDB Portal <--> App Server: Developer copies App ID\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Manual Notification Registration\n\nDeveloper <--> DB Portal: webhook registration UX\nDB Portal -> +DB Notifications: Register: App Server webhook URL, Scope, App ID\nNote over DB Notifications : Confirm Portal Access Token\nDB Notifications -> -DB Portal: notification ID\nDB Portal --> App Server : Developer may copy notification ID\n\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Client Authorization\n\nClient -> +App Server : Request access to DB protected information\nApp Server -> -Client : Redirect to DB Authorization endpoint with authorization request\nClient -> +DB Auth : Redirected authorization request\nClient <--> DB Auth : Authorization UX\nDB Auth -> -Client : Redirect back to App Server with code\nClient -> +App Server : Redirect request back to access server with access code\nApp Server -> +DB Auth : Request tokens with access code\nnote right of DB Service: Cache that this User ID provided access to App ID\nDB Auth -> -App Server : Response with access, refresh, and ID tokens\nnote right of App Server : Cache tokens by user ID\nApp Server -> -Client : Return information to client\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Notification Flow\n\nClient <--> DB Service: Changes to user data - typical via interacting with App Server via Client\nDB Service -> App Server : Notification with notification ID and user ID\nApp Server -> +DB Service : Request changed information with cached access tokens and \"since\" token\nnote over DB Service: Confirm User Access Token\nDB Service -> -App Server : Response with data and new \"since\" token\nnote right of App Server: Update status and cache new \"since\" token\n=== End Text ===\n```\n\n#### 18.1.2. Push notifications, firehose flow\n\n```\n=== Begin Text ===\nnote over Developer, Automation, App Server:\n     An App Developer like MovieMaker\n     Wants to integrate with primary service like Dropbox\nend note\nnote over DB Portal, DB App Registration, DB Notifications, DB Auth, DB Service: The primary service like Dropbox\nnote over Client: The end users' browser or installed app\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : App Registration\n\nalt Automated app registration\n   Developer <--> Automation: Configure\n   Automation -> +DB App Registration: App Name etc.\n   note over DB App Registration: Confirm App Access Token\n   DB App Registration -> -Automation: App ID, App Secret\n   Automation --> App Server : Embed App ID, App Secret\nelse Manual app registration\n   Developer <--> DB Portal : Login into Portal, App Registration UX\n   DB Portal -> +DB App Registration: App Name etc.\n   note over DB App Registration: Confirm Portal Access Token\n\n   DB App Registration -> -DB Portal: App ID\n   DB Portal <--> App Server: Developer copies App ID\nend\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Client Authorization\n\nClient -> +App Server : Request access to DB protected information\nApp Server -> -Client : Redirect to DB Authorization endpoint with authorization request\nClient -> +DB Auth : Redirected authorization request\nClient <--> DB Auth : Authorization UX\nDB Auth -> -Client : Redirect back to App Server with code\nClient -> +App Server : Redirect request back to access server with access code\nApp Server -> +DB Auth : Request tokens with access code\nnote right of DB Service: Cache that this User ID provided access to App ID\nDB Auth -> -App Server : Response with access, refresh, and ID tokens\nnote right of App Server : Cache tokens by user ID\nApp Server -> -Client : Return information to client\n\n\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Notification Registration\n\nApp Server->+DB Notifications: Register: App server webhook URL, Scope, App ID\nnote over DB Notifications : Confirm User Access Token\nDB Notifications -> -App Server: notification ID\nnote right of App Server : Cache the Notification ID and User Access Token\n\n\n\nnote over Developer, Automation, App Server, DB Portal, DB App Registration, DB Notifications, Client : Notification Flow\n\nClient <--> DB Service: Changes to user data - typical via interacting with App Server via Client\nDB Service -> App Server : Notification with notification ID and user ID\nApp Server -> +DB Service : Request changed information with cached access tokens and \"since\" token\nnote over DB Service: Confirm User Access Token\nDB Service -> -App Server : Response with data and new \"since\" token\nnote right of App Server: Update status and cache new \"since\" token\n\n\n\n=== End Text ===\n```\n[fielding]: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm\n[IANA-headers]: https://www.iana.org/assignments/message-headers/message-headers.xhtml\n[rfc-2119]: https://tools.ietf.org/html/rfc2119\n[rfc7231-7-1-1-1]: https://tools.ietf.org/html/rfc7231#section-7.1.1.1\n[rfc-7230-3-1-1]: https://tools.ietf.org/html/rfc7230#section-3.1.1\n[rfc-7231]: https://tools.ietf.org/html/rfc7231\n[rest-in-practice]: https://www.amazon.com/REST-Practice-Hypermedia-Systems-Architecture/dp/0596805829/\n[rest-on-wikipedia]: https://en.wikipedia.org/wiki/Representational_state_transfer\n[rfc-5789]: https://tools.ietf.org/html/rfc5789\n[rfc-5988]: https://tools.ietf.org/html/rfc5988\n[rfc-3339]: https://tools.ietf.org/html/rfc3339\n[rfc-5322-3-3]: https://tools.ietf.org/html/rfc5322#section-3.3\n[cors-preflight]: https://www.w3.org/TR/cors/#resource-preflight-requests\n[rfc-3864]: https://tools.ietf.org/html/rfc3864\n[odata-json-annotations]: https://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Instance_Annotations\n[cors]: https://www.w3.org/TR/access-control/\n[cors-user-credentials]: https://www.w3.org/TR/access-control/#user-credentials\n[cors-simple-headers]: https://www.w3.org/TR/access-control/#simple-header\n[rfc-4627]: https://tools.ietf.org/html/rfc4627\n[iso-8601]: https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15\n[clr-time]: https://msdn.microsoft.com/en-us/library/System.DateTime(v=vs.110).aspx\n[ecmascript-time]: https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.1\n[ole-date]: https://docs.microsoft.com/en-us/windows/desktop/api/oleauto/nf-oleauto-varianttimetosystemtime\n[ticks-time]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724290(v=vs.85).aspx\n[unix-time]: https://msdn.microsoft.com/en-us/library/1f4c8f33.aspx\n[windows-time]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724290(v=vs.85).aspx\n[excel-time]: https://support.microsoft.com/kb/214326?wa=wsignin1.0\n[wikipedia-iso8601-durations]: https://en.wikipedia.org/wiki/ISO_8601#Durations\n[wikipedia-iso8601-intervals]: https://en.wikipedia.org/wiki/ISO_8601#Time_intervals\n[wikipedia-iso8601-repeatingintervals]: https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n[principle-of-least-astonishment]: https://en.wikipedia.org/wiki/Principle_of_least_astonishment\n[odata-breaking-changes]: https://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part1-protocol/odata-v4.0-errata02-os-part1-protocol-complete.html#_Toc406398209\n[websequencediagram-firehose-subscription-setup]: https://www.websequencediagrams.com/cgi-bin/cdraw?lz=bm90ZSBvdmVyIERldmVsb3BlciwgQXV0b21hdGlvbiwgQXBwIFNlcnZlcjogCiAgICAgQW4AEAUAJwkgbGlrZSBNb3ZpZU1ha2VyACAGV2FudHMgdG8gaW50ZWdyYXRlIHdpdGggcHJpbWFyeSBzZXJ2aWNlADcGRHJvcGJveAplbmQgbm90ZQoAgQwLQiBQb3J0YWwsIERCAIEJBVJlZ2lzdHIAgRkHREIgTm90aWZpYwCBLAVzACEGdXRoACsFUwBgBjogVGhlAF0eAIF_CkNsaWVudAAtBmVuZCB1c2VycycgYnJvd3NlciBvciBpbnN0YWxsZWQgYXBwCgCBIQwAgiQgAIFABQCBIS8AgQoGIDogTWFudWFsAIFzEQoKCgCDAgo8LS0-AIIqCiA6IExvZ2luIGludG8Agj8JAII1ECBVWCAKACoKLT4gKwCCWBM6AIQGBU5hbWUgZXRjLgCDFQ4AGxJDb25maXJtAIEBCEFjY2VzcyBUb2tlbgoKAIM3EyAtPiAtAINkCQBnBklEAIEMCwCBVQUAhQIMAIR3CmNvcGllcwArCACCIHAAhHMMAIMKDwCDABg6IHdlYmhvb2sgcgCCeg4AgnUSAIVQDToAhXYHZXIAgwgGAIcTBgBECVVSTCwgU2NvcGUAhzIGSUQKTgCGPQwAhhwNIACDBh4AHhEAgxEPbgCBagwAgxwNAIMaDiAAgx0MbWF5IGNvcHkALREAhVtqAIZHB0F1dGhvcml6AIY7BwCGXQctPiArAIEuDVJlcXVlc3QgYQCFOQZ0byBEQiBwcm90ZWN0ZWQgaW5mb3IAiiQGCgCDBQstPiAtAIctCVJlZGlyZWN0ADYHAGwNIGVuZHBvaW50AIoWBmEADw1yAHYGAIEQDACJVAcASwtlZAAYHgCICAgAMAcAcA4AhGoGAE0FAIEdFmJhY2sgdG8AhF8NaXRoIGNvZGUAghoaaQCBagcAgToHAD0JAII-B3MAPgsAglEHAEsFAIIzDgCBXw0Agn8GdG9rZW5zACcSAI0_BXJpZ2h0IG9mAItpDUNhY2hlIHRoYXQgdGhpcyBVc2VyIElEIHByb3ZpZGVkAINNCwCIZgoAggcJAIN7D3Nwb25zAI0_BwCECgYsIHJlZnJlc2gsIGFuZCBJRACBHAcAgQMPAIYADQCBDAcAgUUGYnkAjFkFIElEAIQkG3R1cm4AhF4MIHRvIGMAjR8FAIwRagCJVw1GbG93AIYqCQCMaQgAgmoKaGFuZ2UAj3YFAIFXBWRhdGEgLSB0eXBpY2FsIHZpYQCQDgVyYWN0aW5nAJAPBgCJQQt2aWEAjnsHCgCPNgogAIhDEACKZw0AkFMFAIkBDwCDDAUAgkYWKwBNCwCHWApjAIEyBQCHRg0AhWUHYWNoAIQeDACEfwVhbmQgInNpbmNlIgCFEQYAkSQOAIR3CgCNfwcAhHQFAIpQEACBUgsAhFAcAII8BWFuZCBuZXcAYRQAhFUTOiBVcGRhdGUgc3RhdHUAgSkGAIFDBQAxEwoKCg&s=mscgen\n[websequencediagram-user-subscription-setup]: https://www.websequencediagrams.com/cgi-bin/cdraw?lz=bm90ZSBvdmVyIERldmVsb3BlciwgQXV0b21hdGlvbiwgQXBwIFNlcnZlcjogCiAgICAgQW4AEAUAJwkgbGlrZSBNb3ZpZU1ha2VyACAGV2FudHMgdG8gaW50ZWdyYXRlIHdpdGggcHJpbWFyeSBzZXJ2aWNlADcGRHJvcGJveAplbmQgbm90ZQoAgQwLQiBQb3J0YWwsIERCAIEJBVJlZ2lzdHIAgRkHREIgTm90aWZpYwCBLAVzACEGdXRoACsFUwBgBjogVGhlAF0eAIF_CkNsaWVudAAtBmVuZCB1c2VycycgYnJvd3NlciBvciBpbnN0YWxsZWQgYXBwCgCBIQwAgiQgAIFABQCBIS8AgQoGIDoAgWwRCgphbHQAgyUIAIEHBiByABQMICAAgxsLPC0tPgCDTws6IENvbmZpZ3VyZQogIACDaAsgLT4gKwCCWBMAegZOYW1lIGV0Yy4AhAgFAIMaDQAfEgBdBXJtAIQ_BUFjY2VzcyBUb2tlAIETBgCDOxIgLT4gLQCBFgxBcHAgSUQAhHwIY3JldACBGxAtPgCFFgsgOiBFbWJlZAAkFGVsc2UgTWFudWFsAIIEJACEbQkgOiBMb2dpbiBpbnRvAIUBCQCBKRFVWACGGAUALQoAgh8mAIIZKwCBCAcAgjoNAIIsHACGLwkAgj8IAIESDgCECAYAh1ELAIdFCmNvcGllcwAuCGVuZACEeGoAhWQHQXV0aG9yaXoAhV8HAIV6By0-ICsAg2ANUmVxdWVzdCBhAIRVBnRvIERCIHByb3RlY3RlZCBpbmZvcgCJQQYKAIQaCy0-IC0AhkoJUmVkaXJlY3QANgcAbA0gZW5kcG9pbnQAiTMGYQAPDXIAdgYAgRAMAIhxBwBLC2VkABgeAIRjCAAwB0EAcQxVWAoASQgAgRwWYmFjayB0bwCFdAwAilwFY29kZQCCGRppAIFpBwCBOQcAPQkAgj0HcwA-CwCCUAcASwUAgjIOAIFeDQCCfgZ0b2tlbnMAJxIAjFsFcmlnaHQgb2YAiwUNQ2FjaGUgdGhhdCB0aGlzIFVzZXIgSUQgcHJvdmlkZWQAg0wLAIU6BwCCBAwAg3oPc3BvbnMAjFsHAIQJBiwgcmVmcmVzaCwgYW5kIElEAIEcBwCBAw8AiDENAIEMBwCBRQZieQCLdQUgSUQAhCMbdHVybgCEXQwgdG8gYwCMOwUKCgCLL2oAjXUMAIwTDwCPNQotPisAjhwQOgCORQdlcgCMVwYAg3YIZWJob29rIFVSTCwgU2NvcGUAkAEGSUQAjwoOAI5rDSAAi2UKAINFBQCLYw0AHBEAgzUOOiBuAIE2DABgCACDCB1oZQCBaQ5JRACDYwUAahIAghB4RmxvdwCJMwkAjE0IAIV0CmhhbmdlAJIcBQCEYQVkYXRhIC0gdHlwaWNhbCB2aWEAkjQFcmFjdGluZwCSNQYAjV8LdmlhAJEhBwoAkVwKIACNfhAAhAsNAJJ5BQCCWQ8AhhYFAIVQFisATQsAimEKYwCBMgUAik8NAIhvB2FjaACHKAwAiAkFYW5kICJzaW5jZSIAiBsGAJNKDgCIAQoAhB0cAIFSCwCHWhwAgjwFYW5kIG5ldwBhFACHXxM6IFVwZGF0ZSBzdGF0dQCBKQYAgUMFADETCgoK&s=mscgen\n"
  },
  {
    "path": "graph/GuidelinesGraph.md",
    "content": "# Microsoft Graph REST API Guidelines\n\nTable of contents\n\n- [Microsoft Graph REST API Guidelines](#microsoft-graph-rest-api-guidelines)\n  - [Introduction](#introduction)\n    - [Legend](#legend)\n  - [Design approach](#design-approach)\n    - [Naming](#naming)\n    - [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)\n    - [Resource modeling patterns](#resource-modeling-patterns)\n      - [Pros and cons](#pros-and-cons)\n      - [Nullable properties](#nullable-properties)\n    - [Query support](#query-support)\n    - [Behavior modeling](#behavior-modeling)\n    - [Error handling](#error-handling)\n    - [Limitations on core types](#limitations-on-core-types)\n  - [External standards](#external-standards)\n  - [API contract and nonbackward compatible changes](#api-contract-and-nonbackward-compatible-changes)\n    - [Versioning and deprecation](#versioning-and-deprecation)\n  - [Recommended API design patterns](#recommended-api-design-patterns)\n  - [References](#references)\n\n\n## Introduction\n\nWhen building a digital ecosystem API usability becomes a business priority. The success of your ecosystem depends on APIs that are easy to discover, simple to use, fit for purpose, and consistent across your products.\n\nThis document offers guidance that Microsoft Graph API producer teams MUST follow to\nensure that Microsoft Graph has a consistent and easy-to-use API surface. A new API design SHOULD meet the following goals:\n\n- Be developer friendly by using consistent naming, patterns, and web standards (HTTP, REST, JSON).\n\n- Work well with SDKs in many programming languages.\n\n- Be sustainable and evolvable by using clear API contracts.\n\nThe Microsoft Graph REST API Guidelines consist of a concise overview document, a collection of articles on Graph standards, and a library of patterns that provide best practices for resolving common API design problems. Together, these documents serve as the means by which API teams discuss and come to consensus on API review requirements.\n\nTechnology and software are constantly changing and evolving, and as such, this document is intended to be a living document. API guidelines that change frequently lead to an uneven and inconsistent API surface.Therefore, the general principles and directions that this document offers will be more stable than the specific recommendations for areas that are new or significantly different. The guidance might change as needed to address new scenarios and to clarify existing guidance. The guidance might change as needed to address new scenarios and to clarify existing guidance. To suggest a change or propose a new idea,\n[open an issue](https://github.com/microsoft/api-guidelines/issues/new/choose).\n\n### Legend\n\nThis document offers prescriptive guidance labeled as follows:\n\n:heavy_check_mark: **MUST** satisfy this specification.\n\n:no_entry: **MUST NOT** use this pattern.\n\n:ballot_box_with_check: **SHOULD** fulfill this specification.\n\n:warning: **SHOULD NOT** adopt this pattern.\n\nIf you do not follow this advice, you MUST disclose your reasons during the Microsoft Graph API review.\n\n## Design approach\n\nThe design of your API is arguably the most important investment you'll make. API design is what creates the first impression for developers when they discover and learn how to use your APIs. We promote an API-first design approach where you begin your product design by focusing on how information is exchanged and represented and by creating an interface contract for your API, which is followed by design and implementation of the backing service. This approach ensures decoupling of the interface from your implementation and is essential for agility, predictability, and reuse of your APIs.\n\nAn established interface contract allows developers to use your API while internal teams are still working on implementation; API specifications enable designing user experience and test cases in parallel. Starting with user-facing contracts also promotes a good understanding of system interactions, your modeling domain, and an understanding of how the service will evolve.\n\nMicrosoft Graph supports resource and query-based API styles that follow HTTP, REST, and JSON standards, where the API contract is described by using OData conventions and schema definitions. For more information, see [Documentation · OData Version 4.01](https://www.odata.org/documentation/).\n\nIn general, API design includes the following steps:\n\n1. Outline the key current and future scenarios for API consumers.\n  \n1. Define your domain model.\n\n1. Derive and name your API resources.\n  \n1. Describe relationships between resources.\n\n1. Determine required behavior.\n\n1. Determine user roles and application permissions.\n\n1. Specify errors.\n\nWhen creating your API contract, you define resources based on the domain model supporting your service and identify interactions based on user scenarios. Good API design goes beyond modeling the current state of resources. It's important to plan ahead how the API evolves; to do this, it's essential to understand and document your user scenarios as the foundation of the API design. There's no one-to-one correspondence between domain model elements and API resources because you SHOULD simplify your customer facing APIs for better usability and to obfuscate implementation details.\n\nWe recommend creating a simple resource diagram like the following to show resources and their relationships and make it easier to reason about modeling choices and the shape of your API.\n\n![Resource model example](ModelExample.png)\n\nAfter you define your resources, it’s time to think about the behavior of your API, which can be expressed via HTTP methods and operational resources such as functions and actions. As you think about API behavior, you identify a happy path and various exceptions and deviations that are expressed as errors and represented by using HTTP codes and error messages.\n\nAt every step of your design, you need to consider security, privacy, and compliance as intrinsic components of your API implementation.\n\n### Naming\n\nAPI resources are typically described by nouns. Resource and property names appear in API URLs and payloads and MUST be descriptive and easy to understand. Ease of understanding comes from familiarity and recognition; therefore, when thinking about naming, you SHOULD favor consistency with other Microsoft Graph APIs, names in the product user interface, and industry standards. Microsoft Graph naming conventions follow the [Naming guidelines](./articles/naming.md).\n\nFollowing is a short summary of the most often used conventions.\n\n| Requirements                                                            | Example                       |\n| ------------------------------------------------------------------------|-------------------------------|\n| :no_entry: **MUST NOT** use redundant words in names.                   | - **Right:** /places/{id}/**displayName** or /phones/{id}/**number** <BR> -  **Wrong:** /places/{id}/**placeName** or /phones/{id}/**phoneNumber** |\n| :warning: **SHOULD NOT** use brand names in type or property names.     | - **Right:** chat   <BR> -  **Wrong:** teamsChat <BR> - **NOTE:** there is an exception for resources that *only* exist under the `/admin` root segment and the `/users/{userId}/settings` path.  |\n| :warning: **SHOULD NOT** use acronyms or abbreviations unless they are broadly understood. | - **Right:** url or htmlSignature <BR> - **Wrong:** msodsUrl or dlp |\n| :heavy_check_mark: **MUST** use singular nouns for non-enum type names.          | - **Right:** address  <BR> - **Wrong:** addresses  |\n| :heavy_check_mark: **MUST** use singular nouns for non-flags enum type names.          | - **Right:** color  <BR> - **Wrong:** colors  |\n| :heavy_check_mark: **MUST** use plural nouns for flags enum type names.          | - **Right:** diplayMethods  <BR> - **Wrong:** displayMethod  |\n| :heavy_check_mark: **MUST** use plural nouns for collections (for listing type or collection properties). | - **Right:** addresses <BR> - **Wrong:** address |\n| :ballot_box_with_check: **SHOULD** pluralize the noun even when followed by an adjective (a *postpositive*).| - **Right:** passersby or mothersInLaw    <BR> -  **Wrong:** notaryPublics or motherInLaws |\n| **CASING** | |\n| :heavy_check_mark: **MUST** use lower camel case for *all* names and namespaces.   | - **Right:** automaticRepliesStatus <BR> - **Wrong:** kebab-case or snake_case |\n| :ballot_box_with_check: **SHOULD** case two-letter acronyms with the same case.   | - **Right:** ioLimit or totalIOAmount <BR> - **Right:** 'id' properties similar to driveId or applicationId <BR> - **Wrong:** iOLimit or totalIoAmount|\n| :ballot_box_with_check: **SHOULD** case `id` properties the same as a normal word.   | - **Right:** id or fileId <BR> - **Wrong:** ID or fileID |\n| :ballot_box_with_check: **SHOULD** case three+ letter acronyms the same as a normal word.  | - **Right:** fidoKey or oauthUrl <BR> - **Wrong:** webHTML |\n| :no_entry: **MUST NOT** capitalize the word following a [prefix](https://www.thoughtco.com/common-prefixes-in-english-1692724) or words within a [compound word](http://www.learningdifferences.com/Main%20Page/Topics/Compound%20Word%20Lists/Compound_Word_%20Lists_complete.htm).                                     | - **Right:** subcategory, geo coordinate, or crosswalk <BR> - **Wrong:** metaData, semiCircle, or airPlane |\n| :heavy_check_mark: **MUST** capitalize within hyphenated and open (spaced) compound words. | - **Right:** fiveYearOld, daughterInLaw, or postOffice <BR> - **Wrong:** paperclip or fullmoon |\n| **PREFIXES AND SUFFIXES** | |\n| :heavy_check_mark: **MUST** suffix date and time properties with Date, Time, or DateTime  | - **Right:** dueDate—an Edm.Date <BR> - **Right:** recurringMeetingTime—an Edm.TimeOfDay <BR> - **Right:** createdDateTime—an Edm.DateTimeOffset <BR>- **Wrong:** dueOn or startTime <BR> - **Right:** Instead, both of the preceding are an Edm.DateTimeOffset |\n| :ballot_box_with_check: **SHOULD** use the Duration type for durations, but if using an `int`, append the units. | - **Right:** passwordValidityPeriod—an Edm.Duration <BR> - **Right:** passwordValidityPeriodInDays — an Edm.Int32 (use of Edm.Duration type is preferable) <BR>- **Wrong:** passwordValidityPeriod — an Edm.Int32 |\n| :no_entry: **MUST NOT** use suffix property names with primitive type names unless the type is temporal. | - **Right:** isEnabled or amount <BR> - **Wrong:** enabledBool |\n| :ballot_box_with_check: **SHOULD** prefix property names for properties concerning a different entity.   | - **Right:** siteWebUrl on driveItem or userId on auditActor <BR> - **Wrong:** webUrl on contact when it's the companyWebUrl |\n| :ballot_box_with_check: **SHOULD** prefix Boolean properties with `is`, unless this leads to awkward or unnatural sounding names for Boolean properties. | - **Right:** isEnabled or isResourceAccount <BR>- **Wrong:** enabled or allowResourceAccount <BR>- **Right:** hasChildren or hasSubscriptions <BR>-  **Wrong:** isChildren or isSubscriptions <BR>- **Right:** allowNewTimeProposals or allowInvitesFrom (subjectively more natural than the following examples) <BR> - **Wrong:** isNewTimeProposalsAllowed or isInvitesFromAllowed (subjectively more awkward that the preceding examples) |\n| :no_entry: **MUST NOT** use collection, response, or request suffixes.  | - **Right:** addresses <BR> - **Wrong:** addressCollection |\n\n#### Tree and graph structures\n\nWhen a tree or graph structure is being modeled, the direct sub-nodes are usually named `children` or `members`. \nIf a property is desired that represents a \"flattened\" data structure, the property **SHOULD** be prefixed with \"transitive\", e.g. `transitiveChildren` or `transitiveMembers`.\nSuch properties **MUST** represent a mathematically [transitive relationship](https://en.wikipedia.org/wiki/Transitive_relation). \nTo simplify, if `A` is a child of `B` and `B` is a child of `C`, then `A` is a child of `C` via a transitive relationship; this **MUST** be true for properties using word \"transitive\" in their name.\n\n### Uniform Resource Locators (URLs)\n\nA Uniform Resource Locator (URL) is how developers access the resources of your API.\n\nNavigation paths to Microsoft Graph resources are broken into multiple segments,\n`{scheme}://{host}/{version}/{category}/[{pathSegment}][?{query}]` where:\n\n- `scheme` and `host` segments are always [`https://graph.microsoft.com`](https://graph.microsoft.com/v1.0/users).\n\n- `version` can be v1.0 or beta.\n\n- `category` is a logical grouping of APIs into top-level categories.\n\n- `pathSegment` is one or many navigation segments that can address an entity, collection of entities, property, or operation available for an entity.\n\n- `query` string MUST follow the OData standard for query representations and is covered in the Query section of OData specifications.\n\nWhile HTTP defines no constraints on how different resources are related, it does encourage the use of URL path segment hierarchies to convey relationships. In Microsoft Graph, relationships between resources are supported by the OData concepts of singletons, entity sets, entities, complex types, and navigation properties.\n\nIn Microsoft Graph, a top-level API category might represent one of the following groupings:\n\n- A core *user-centric concept* of Microsoft Graph: /users, /groups, or /me.\n\n- A Microsoft *product or service offering* covering multiple use cases: /teamwork, /directory.\n\n- A *feature offering* covering a single use case and *shared* across multiple Microsoft products: /search, /notifications, /subscriptions.\n\n- *Administrative configuration* functions for specific products: /admin/exchange.\n\n- Internal Microsoft requirements for publishing Privileged and Hidden APIs, routing, and load testing: /loadTestEntities.\n\nEffectively, top-level categories define a perimeter for the API surface; thus, a new category creation requires additional rigor and governance approval.\n\n### Resource modeling patterns\n\nYou can model structured resources for your APIs by using the OData entity type or complex type. The main difference between these types is that an entity type declares a key property to uniquely identify its objects, and a complex type doesn't. In Microsoft Graph, this key property is called `id` for server-created key values. If there's a natural name for the key property, then the workload can use that.\n\nBecause objects of complex types in Microsoft Graph don’t have unique identifiers, they are not directly addressable via URIs. Therefore, you SHOULD use entity types to model addressable resources such as individually addressable items within a collection. For more information, see the [Collection guidance](./articles/collections.md). Complex types are better suited to represent composite properties of API entities.\n\n```xml\n <EntityType Name=\"author\">\n    <Key>\n        <PropertyRef Name=\"id\" />\n    </Key>\n    <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n    <Property Name=\"name\" Type=\"Edm.String\" />\n    <Property Name=\"address\" Type=\"microsoft.graph.Address\" />\n</EntityType>\n<ComplexType Name=\"address\">\n    <Property Name=\"city\" Type=\"Edm.String\" />\n    <Property Name=\"street\" Type=\"Edm.String\" />\n    <Property Name=\"stateOrProvince\" Type=\"Edm.String\" />\n    <Property Name=\"country\" Type=\"Edm.String\" />\n</ComplexType>\n```\n\n|  Microsoft Graph rules for modeling complex resources                                       |\n|---------------------------------------------------------------------------------------------|\n| :heavy_check_mark: **MUST** use String type for ID.                                         |\n| :heavy_check_mark: **MUST** use a primary key composed of a single property.                |\n| :heavy_check_mark: **MUST** use an object as the root of all JSON payloads.                 |\n| :heavy_check_mark: **MUST** use a root object with a value property to return a collection. |\n| :heavy_check_mark: **MUST** include @odata.type annotations when the type is ambiguous.     |\n| :warning: **SHOULD NOT** add the property ID to a complex type.                             |\n\nThere are different approaches for designing an API resource model in situations with multiple variants of a common concept.\nThe three most often used patterns in Microsoft Graph today are type hierarchy, facets, and flat bag of properties:\n\n- **[Type hierarchy](./patterns/subtypes.md)** is represented by one abstract base type with a few common properties and one subtype for each variant.\n\n- **[Facets](./patterns/facets.md)** are represented by a single entity type with common properties and one facet property (of complex type) per variant. The facet properties only have a value when the object represents that variant.\n\n- **[Flat bag of properties](./patterns/flat-bag.md)** is represented by one entity type with all the potential properties plus an additional property to distinguish the variants, often called type. The type property describes the variant and also defines properties that are required or meaningful for the variant given by the type property.\n\n- **[Enums](./patterns/enums.md)** represent a subset of the nominal type they rely on, and are especially useful in cases where certain properties have predefined, limited options.\n\nThe following table shows a summary of the main qualities for each pattern and can help you select a pattern fit for your use case.\n\n| API qualities\\patterns  | Properties and behavior described in metadata | Supports combinations of properties and behaviors | Simple query construction |\n|-------------------------|-----------------------------------------------|---------------------------------------------------|---------------------------|\n| Type hierarchy          | yes                                           | no                                                | no                        |\n| Facets                  | partially                                     | yes                                               | yes                       |\n| Flat bag                | no                                            | no                                                | yes                       |\n\n#### Pros and cons\n\nFollowing are a few pros and cons to decide which pattern to use:\n\n- In **[hierarchy](./patterns/subtypes.md)**, the interdependencies of properties, that is, which properties are relevant for which variants, is fully captured in metadata, and client code can potentially leverage that to construct and/or validate requests.\n\n- Introducing new cases in **hierarchy** is relatively isolated (which is why it is so familiar to OOP) and is considered backwards compatible (at least syntactically).\n\n- Introducing new cases/variants in **[facets](./patterns/facets.md)** is straightforward. You need to be careful because it can introduce situations where previously only one of the facets was non-null and now all the old ones are null. This is not unlike adding new subtypes in the **hierarchy** pattern or adding a new type value in the **[flat bag](./patterns/flat-bag.md)** pattern.\n\n- **hierarchy** and **facets** (to a slightly lesser degree) are well-suited for strongly typed client programming languages, whereas **flat bag** is more familiar to developers of less strongly typed languages.\n\n- **facets** has the potential to model what is typically associated with multiple inheritances.\n\n- **facets** and **flat bag** lend to syntactically simpler filter query expression. **hierarchy** is more explicit but requires the cast segments in the filter query.\n\n- **hierarchy** can be refined by annotating the collections with OData derived type constraints; see [validation vocabulary](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Validation.V1.md). This annotation restricts the values to certain sub-trees of an inheritance **hierarchy**. It makes it explicit that the collection only contains elements of some of the subtypes and helps to not return objects of a type that are semantically not suitable.\n\n> **Note:**\n> As can be seen in a few of the pros and cons, one of the important aspects discussed here is that the API design goes beyond the syntactical aspects of the API. Therefore, it is important to plan ahead how the API evolves, lay the foundation, and allow users to form a good understanding of the semantics of the API. **Changing the semantics is always a breaking change.** The different modeling patterns differ in how they express syntax and semantics and how they allow the API to evolve without breaking compatibility. For more information, see [API contract and non-backward compatible changes](#api-contract-and-non-backward-compatible-changes) later in this article.\n\n#### Nullable properties\n\nThe facet and flat bag approaches often require nullable properties, so it is important to still use non-nullable properties where appropriate.\nSince inheritance can often remove the use of nullable properties completely, it is also important to know when nullable properties are necessary.\nSee [Nullable properties](./articles/nullable.md) for more details.\n\n### Query support\n\nMicrosoft Graph APIs returning collections of resources SHOULD support basic query options in conformance with [OData specifications](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody) and [Collection guidance](./articles/collections.md).\n\n|Requirements                                                                                        |\n|----------------------------------------------------------------------------------------------------|\n| :heavy_check_mark: **MUST** support `$select on resource` to enable properties projection. |\n| :ballot_box_with_check: **SHOULD** support `/entityTypeCollection/{id}?$expand=navProp1` option for navigation properties of entities. |\n| :ballot_box_with_check: **SHOULD** support `$filter` with `eq` and `ne` operations on properties of entity collections. |\n| :heavy_check_mark: **MUST** support pagination of collections (of entity types or complex types) using a [nextLink](http://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_ControlInformationnextLinkodatanextL).  |\n| :ballot_box_with_check: **MAY** support [server-driven pagination](./articles/collections.md#81-server-driven-paging) of collections using `$skiptoken`.  |\n| :ballot_box_with_check: **SHOULD** support [client-driven pagination](./articles/collections.md#82-client-driven-paging) of collections using `$top` and `$skip`. |\n| :ballot_box_with_check: **SHOULD** support `$count` for collections. |\n| :ballot_box_with_check: **SHOULD** support sorting with `$orderby` both ascending and descending on properties of the entities. |\n\nThe query options part of an OData URL can be long, potentially exceeding the maximum length of URLs supported by components involved in transmitting or processing the request. One way to avoid this is to use the POST verb instead of GET with the `$query` segment, and pass the query options part of the URL in the request body as described in the chapter\n[OData Query Options](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody).\n\nAnother way to avoid this is to use JSON batch as described in the [Microsoft Graph batching documentation](https://docs.microsoft.com/graph/json-batching#bypassing-url-length-limitations-with-batching).\n\n### Behavior modeling\n\nThe HTTP operations dictate how your API behaves. The URL of an API, along with its request/response bodies, establishes the overall contract that developers have with your service. As an API provider, how you manage the overall request/response pattern SHOULD be one of the first implementation decisions you make.\n\nIf possible, APIs SHOULD use resource-based designs with standard HTTP methods rather than operation resources. Operation resources are either functions or actions. According to [OData standards](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31359009), a function represents an operation that returns a single instance or collection of instances of any type and doesn’t have an observable side effect. An action might have side effects and might return a result represented as a single entity or collection of any type.\n\n|  Microsoft Graph rules for behavior modeling                     |\n|------------------------------------------------------------------|\n| :heavy_check_mark: **MUST** use POST to create new entities in insertable entity sets or collections.<BR>This approach requires the service to produce a system-generated key, or for a caller to provide a key in the request payload. |\n| :ballot_box_with_check: **SHOULD** additionally use PATCH to create new entities in insertable entity sets or collections.<BR>This [Upsert](./patterns/upsert.md) approach requires the caller to provide a key in the request URL. |\n| :heavy_check_mark: **MUST** use PATCH to edit updatable resources.  |\n| :heavy_check_mark: **MUST** use DELETE to delete deletable resources. |\n| :heavy_check_mark: **MUST** use GET for listing and reading resources. |\n| :warning: **SHOULD NOT** use PUT for updating resources. |\n| :ballot_box_with_check: **SHOULD** avoid using multiple round trips to complete a single logical operation. |\n\nOperation resources MUST have a binding parameter that matches the type of the bound resource. In addition, both actions and functions support overloading, meaning an API definition might contain multiple actions or functions with the same name.\n\nFor an additional list of standard HTTP methods, see the [RFC7231 Hypertext Transfer Protocol](https://www.rfc-editor.org/rfc/rfc7231).\n\n### Error handling\n\n To improve API traceability and consistency you MUST use the recommended Microsoft Graph error model and the Microsoft Graph utilities library to provide a standard implementation for your service. The value for the \"message\" name/value pair MUST be a human-readable representation of the error, tailored to provide enough information for the developer to understand the error and take appropriate action. The message is intended only as an aid to developers and should not be exposed to end users.\n\n```http\n{\n\"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"Cannot process the request because a required field is missing.\",\n    \"target\": \"query\",    \n    \"innererror\":{\n      \"code\": \"requiredFieldMissing\"             \n     }\n}\n```\n\nThe top-level error code MUST match the HTTP response status code description, converted to camelCase, as listed in the [Status Code Registry (iana.org)](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml). The following examples demonstrate error modeling for common use cases:\n\n- **Simple error**: An API wants to report an error with top-level details only. The error object contains the top-level error code, message and target (optional).\n\n   ```http\n    {\n      \"error\": {\n        \"code\": \"badRequest\",\n        \"message\": \"Cannot process the request because it is malformed or incorrect.\",\n        \"target\": \"resource\"\n      }\n    }\n   ```\n\n- **Detailed error**: An API needs to provide service-specific details of the error via the innererror property of the error object. It is intended to allow services to supply a specific error code to help differentiate errors that share the same top-level error code but are reported for different reasons.\n    \n   ```http\n    {\n      \"error\": {\n        \"code\": \"badRequest\",\n        \"message\": \"Cannot process the request because a required field is missing.\",\n        \"innererror\": {\n          \"code\": \"requiredFieldOrParameterMissing\"                   \n        }\n      }\n    }\n   ```\n\n| Microsoft Graph enforces the following error rules                                                                | \n|-------------------------------------------------------------------------------------------------------------------|\n| :heavy_check_mark: **MUST** return an error property with a child code property in all error responses. |\n| :heavy_check_mark: **MUST** return a 403 Forbidden error when the application or signed-in user has insufficient permissions present in the auth token. |\n| :heavy_check_mark: **MUST** return a 429 Too Many Requests error when the client exceeded throttling limits, and a 503 Service Unavailable error when the service overloaded but the client is within throttling limits.|\n| :ballot_box_with_check: **SHOULD** return a 404 Not Found error if a 403 error would result in information disclosure. |\n\nFor more detailed guidance, see the article on [Error condition responses](./articles/errorResponses.md).\n\nFor a complete mapping of error codes to HTTP statuses, see\n[rfc7231 (ietf.org)](https://datatracker.ietf.org/doc/html/rfc7231#section-6).\n\n<a name=\"api-contract-and-non-backward-compatible-changes\"></a>\n\n### Limitations on core types\n\nThe types `user`, `group`, and `device` should not have any new structural property(s) added, without compelling justification.\nInstead, model the concept represented in those property(s) as a new entity and do one of the following:\n1. Add navigation from `user`, `group`, or `device` to the new entity.\n2. Add a navigation from the new entity to `user`, `group` or `device`.\n\nMore details and examples are available in [Core types](./articles/coreTypes.md).\n\n## External standards\n\nFor ease of client use and interoperatibility, some APIs might implement a standard that is defined external to Microsoft Graph and OData. \nWorkloads SHOULD follow these standards exactly, even if they conflict with the OData standard and/or the Microsoft Graph guidelines. \nWorkloads SHOULD define these standards in their CSDL model if they do not conflict with the OData standard.\nStandards that *do* conflict with the OData standard might be defined in the CSDL in one of two ways:\n1. Using `Edm.Untyped` only and support for the external standard will come directly from the service implementation; OR\n2. Adding CSDL elements to model the external standard using `Edm.String` for `EnumType`s that conflict with the OData standard and `Edm.Untyped` wherever any other conflict with the OData standard occurs.\n\nIn either case, any use of `Edm.String` instead of an `EnumType` or any use of `Edm.Untyped` MUST provide a [description annotation](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.xml#L105) to document references to the standard that the client is expected to follow.\nThe benefit of the second approach is that strongly-typed models have SDK support for clients and also have significant tooling support for both the workload and clients.\nNote that it's backwards compatible for a workload to migrate from the second approach to the first approach in case the external standard is *initially* compliant with the OData standard and *later* conflicts with the OData standard. \n\n## API contract and nonbackward compatible changes\n\nThe Microsoft Graph defines breaking changes as any change that requires a client to change its implementation to continue working with the service, it includes changes to the API contract, API behavior, and nonbackward compatible changes.\nIn general, making all but additive changes to the API contract for existing elements is considered breaking. Adding new elements is allowed and is not considered a breaking change.\n\n**Non-breaking changes:**\n\n- To add properties that are nullable or have a default value\n- Adding a member after the sentinel member to an evolvable enumeration\n- Removing, renaming, or changing the type of annotation\n- Changing the order of properties\n- Changing the length or format of opaque strings, such as resource IDs\n- Adding or removing an annotation OpenType=\"true\"\n\n**Breaking changes:**\n\n- Changing the URL or fundamental request/response associated with a resource\n- Removing, renaming, or changing an incompatible type of a declared property\n- Removing or renaming APIs or API parameters\n- Adding a required request header\n- Adding EnumType members for nonevolvable enumerations\n- Adding Nullable=\"false\" properties to existing types\n- Adding a parameter not marked as [Nullable](http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_Nullable) to existing actions\n- Adding a parameter not marked as [Optional](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#OptionalParameter) to an existing function\n- Changing top-level error codes\n- Introducing server-side pagination to existing collections\n- Making significant changes to the performance of APIs such as increased latency, rate limits, or concurrency\n\nThe applicable changes described in the [Model Versioning of the OData V4.01 spec](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ModelVersioning) SHOULD be considered part of the minimum bar that all services MUST consider a breaking change.\n\n### Versioning and deprecation\n\nAs the market and technology evolves, your APIs will require modifications. In this case, you MUST avoid breaking changes and add new resources and features incrementally. If that isn't possible, then you MUST version elements of your APIs. Microsoft Graph allows versioning of elements, including entities and properties. Versioning involves adding a new, uniquely named version of the element and marking the old version as deprecated.\n\nIn some cases, there's a natural new name for the element. In other cases, where the original name is still the most descriptive, the suffix _v2 can be added to the original name to make it unique. The original element is then marked as deprecated by using annotations.\n\nMicrosoft Graph provides two public endpoints to support the API lifecycle:\n- [API sets on the v1.0 endpoint](https://graph.microsoft.com/v1.0) are in general availability (GA) status.\n- [API sets on the beta endpoint](https://graph.microsoft.com/beta) are in beta or private preview status.\n\nMicrosoft Graph APIs in the GA version guarantee API stability and consistency for its clients. If your API requires a breaking change in GA, then you MUST create new element versions and support deprecated elements for a minimum of 36 months or 24 months with demonstrated non-usage.\n\nOn the beta endpoint, breaking changes and deprecation of APIs are allowed with consideration of dependencies and customer impact. It is a best practice to test new element versions on the beta endpoint at first and then promote API changes to the GA endpoint.\n\nDetailed requirements for versioning and deprecation are described in the [Deprecation guidelines](./articles/deprecation.md).\n\n## Recommended API design patterns\n\nThe guidelines in previous sections provide a brief overview and a quick start for Microsoft Graph API developers. For a more detailed dive into a specific topic, you can explore [additional articles](./articles/) or learn more about [modeling patterns with the Microsoft Graph](./patterns/) listed in the following table.\n\n| Pattern                                          | Description                                                                |\n|--------------------------------------------------|----------------------------------------------------------------------------|\n| [Alternate key](./patterns/alternate-key.md)     | Uniquely identify and query resources using an alternate key.              |\n| [Change tracking](./patterns/change-tracking.md) | Keep API consumers in sync with changes without polling.                   |\n| [Collection subsets](./patterns/subsets.md) | Model collection subsets   |\n| [Default properties](./patterns/default-properties.md) | Omit non-default properties from the response unless they are explicitly requested using `$select`.\n| [Dictionary](./patterns/dictionary.md)           | Clients can provide an unknown quantity of data elements of the same type. |\n| [Evolvable enums](./patterns/evolvable-enums.md) | Extend enumerated types without breaking changes.                          |\n| [Facets](./patterns/facets.md)                   | Model parent-child relationships.                                          |\n| [Flat bag](./patterns/flat-bag.md)               | Model variants of the same type.                                           |\n| [Long running operations](./patterns/longRunningOperations.md)| Model operations where processing a client request takes a long time. |\n| [Modeling subsets](./patterns/subsets.md)        | Model collection subsets for All, None, Included, or Excluded criteria.    |\n| [Namespace](./patterns/namespace.md)             | Organize resource definitions into a logical set.                          |\n| [Navigation properties](./patterns/navigation-property.md) | Model resource relationships                         |\n| [Operations](./patterns/operations.md) | Model complex business operations                          |\n| [Type hierarchy](./patterns/subtypes.md)         | Model `is-a` relationships using subtypes.                                 |\n| [Upsert](./patterns/upsert.md)                   | Idempotent operation to create or update a resource using a client-provided key.   |\n| [Viewpoint](./patterns/viewpoint.md)         | Model user specific properties for a shared resource. |\n\n## References\n\n- [Microsoft Graph documentation](https://docs.microsoft.com/graph/overview)\n- [Microsoft REST API Guidelines-deprecated](Guidelines-deprecated.md)\n- [OData guidelines](http://www.odata.org/documentation/)\n- [Azure RESTful web API design](https://docs.microsoft.com/azure/architecture/best-practices/api-design)\n- [Graph Explorer](https://developer.microsoft.com/graph/graph-explorer)\n"
  },
  {
    "path": "graph/articles/collections.md",
    "content": "# Collections\n\n## 1. Item keys\n\nServices SHOULD support durable identifiers for each item in the collection, and that identifier SHOULD be represented in JSON as \"id\". These durable identifiers are often used as item keys.\n\nCollections MAY support delta queries, see the [Change Tracking pattern](../patterns/change-tracking.md) section for more details.\n\n## 2. Serialization\n\nCollections are represented in JSON using standard array notation for `value` property.\n\n## 3. Collection URL patterns\n\nWhile there are multiple collections located directly under the Graph root going forward, you MUST have a singleton for the top-level segment and scope collections to an appropriate singleton. Collection names SHOULD be plural nouns when possible. Collection names shouldn't use suffixes, such as \"Collection\" or \"List\".\n\nFor example:\n\n```http\nGET https://graph.microsoft.com/v1.0/teamwork/devices\n```\n\nCollections elements MUST be addressable by a unique id property. The id property MUST be a String and MUST be unique within the collection. The id property MUST be represented in JSON as \"id\".\nFor example:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices/0f3ce432-e432-0f3c-32e4-3c0f32e43c0f\n```\n\nWhere:\n\n- \"https://graph.microsoft.com/beta/teamwork\" - the service root represented as the combination of host (site URL) + the root path to the service.\n- \"devices\" – the name of the collection, unabbreviated, pluralized.\n- \"0f3ce432-e432-0f3c-32e4-3c0f32e43c0f\" – the value of the unique id property that MUST be the raw string/number/guid value with no quoting but properly escaped to fit in a URL segment.\n\n### 3.1. Nested collections and properties\n\nCollection items MAY contain other collections.\nFor example, a devices collection MAY contain device resources that have multiple mac addresses:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices/0f3ce432-e432-0f3c-32e4-3c0f32e43c0f\n```\n\n```json\n\n{\n  \"value\": {\n    \"@odata.type\": \"#microsoft.graph.teamworkDevice\",\n    \"id\": \"0f3ce432-e432-0f3c-32e4-3c0f32e43c0f\",\n    \"deviceType\": \"CollaborationBar\",\n    \"hardwareDetail\": {\n      \"serialNumber\": \"0189\",\n      \"uniqueId\": \"5abcdefgh\",\n      \"macAddresses\": [],\n      \"manufacturer\": \"yealink\",\n      \"model\": \"vc210\"\n    },\n    ...    \n  }\n}\n```\n\n## 4. Big collections\n\nAs data grows, so do collections.\nServices SHOULD support server-side pagination from day one even for all collections, as adding pagination is a breaking change.\nWhen multiple pages are available, the serialization payload MUST contain the opaque URL for the next page as appropriate.\nRefer to the [paging guidance](../Guidelines-deprecated.md#98-pagination) for more details.\n\nClients MUST be resilient to collection data being either paged or nonpaged for any given request.\n\n```json\n{\n  \"value\":[\n    { \"id\": \"Item 1\",\"price\": 9 95,\"sizes\": null},\n    { … },\n    { … },\n    { \"id\": \"Item 99\",\"price\": 5 99,\"sizes\": null}\n  ],\n  \"@nextLink\": \"{opaqueUrl}\"\n}\n```\n\n## 5. Changing collections\n\nPOST requests are not idempotent.\nThis means that two POST requests sent to a collection resource with exactly the same payload MAY lead to multiple items being created in that collection.\nThis is often the case for insert operations on items with a server-side generated id.\nFor additional information refer to [Upsert pattern](../patterns/upsert.md).\n\nFor example, the following request:\n\n```http\nPOST https://graph.microsoft.com/beta/teamwork/devices\n```\n\nWould lead to a response indicating the location of the new collection item:\n\n```http\n201 Created\nLocation: https://graph.microsoft.com/beta/teamwork/devices/123\n```\n\nAnd once executed again, would likely lead to another resource:\n\n```http\n201 Created\nLocation: https://graph.microsoft.com/beta/teamwork/devices/124\n```\n\n## 6. Sorting collections\n\nThe results of a collection query MAY be sorted based on property values.\nThe property is determined by the value of the _$orderBy_ query parameter.\n\nThe value of the _$orderBy_ parameter contains a comma-separated list of expressions used to sort the items.\nA special case of such an expression is a property path terminating on a primitive property.\n\nThe expression MAY include the suffix \"asc\" for ascending or \"desc\" for descending, separated from the property name by one or more spaces.\nIf \"asc\" or \"desc\" is not specified, the service MUST order by the specified property in ascending order.\n\nNULL values MUST sort as \"less than\" non-NULL values.\n\nItems MUST be sorted by the result values of the first expression, and then items with the same value for the first expression are sorted by the result value of the second expression, and so on.\nThe sort order is the inherent order for the type of the property.\n\nFor example:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$orderBy=companyAssetTag\n```\n\nWill return all devices sorted by companyAssetTag in ascending order.\n\nFor example:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$orderBy=companyAssetTag desc\n```\n\nWill return all devices sorted by companyAssetTag in descending order.\n\nSub-sorts can be specified by a comma-separated list of property names with OPTIONAL direction qualifier.\n\nFor example:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$orderBy=companyAssetTag desc,activityState\n```\n\nWill return all devices sorted by companyAssetTag in descending order and a secondary sort order of activityState in ascending order.\n\nSorting MUST compose with filtering see [Odata 4.01 spec](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361038) for more details.\n\n### 6.1. Interpreting a sorting expression\n\nSorting parameters MUST be consistent across pages, as both client and server-side paging is fully compatible with sorting.\n\nIf a service does not support sorting by a property named in a _$orderBy_ expression, the service MUST respond with an error message as defined in the Responding to Unsupported Requests section.\n\n## 7. Filtering\n\nThe _$filter_ querystring parameter allows clients to filter a collection of resources that are addressed by a request URL.\nThe expression specified with _$filter_ is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response.\nResources for which the expression evaluates to false or to null, or which reference properties that are unavailable due to permissions, are omitted from the response.\n\nExample: return all devices with activity state equal to 'Active'\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$filter=(activityState eq 'Active') \n```\n\nThe value of the _$filter_ option is a Boolean expression.\n\n### 7.1. Filter operations\n\nServices that support _$filter_ SHOULD support the following minimal set of operations.\n\nOperator             | Description           | Example\n-------------------- | --------------------- | -----------------------------------------------------\nComparison Operators |                       |\neq                   | Equal                 | city eq 'Redmond'\nne                   | Not equal             | city ne 'London'\ngt                   | Greater than          | price gt 20\nge                   | Greater than or equal | price ge 10\nlt                   | Less than             | price lt 20\nle                   | Less than or equal    | price le 100\nLogical Operators    |                       |\nand                  | Logical and           | price le 200 and price gt 3.5\nor                   | Logical or            | price le 3.5 or price gt 200\nnot                  | Logical negation      | not price le 3.5\nGrouping Operators   |                       |\n( )                  | Precedence grouping   | (priority eq 1 or city eq 'Redmond') and price gt 100\n\nServices MUST use the following operator precedence for supported operators when evaluating _$filter_ expressions.\nOperators are listed by category in order of precedence from highest to lowest.\nOperators in the same category have equal precedence:\n\n| Group           | Operator | Description           |\n|:----------------|:---------|:----------------------|\n| Grouping        | ( )      | Precedence grouping   |\n| Unary           | not      | Logical Negation      |\n| Relational      | gt       | Greater Than          |\n|                 | ge       | Greater Than or Equal |\n|                 | lt       | Less Than             |\n|                 | le       | Less Than or Equal    |\n| Equality        | eq       | Equal                 |\n|                 | ne       | Not Equal             |\n| Conditional AND | and      | Logical And           |\n| Conditional OR  | or       | Logical Or            |\n\n## 8. Pagination\n\nRESTful APIs that return collections MAY return partial sets.\nConsumers of these services MUST expect partial result sets and correctly page through to retrieve an entire set.\n\nThere are two forms of pagination that MAY be supported by RESTful APIs.\nServer-driven paging allows servers to even out load across clients and mitigates against denial-of-service attacks by forcibly paginating a request over multiple response payloads.\nClient-driven paging enables clients to request only the number of resources that it can use at a given time.\n\nSorting and Filtering parameters MUST be consistent across pages, because both client- and server-side paging is fully compatible with both filtering and sorting.\n\n### 8.1. Server-driven paging\n\nPaginated responses MUST indicate a partial result by including a `@odata.nextLink` token in the response.\nThe absence of a `nextLink` token means that no additional pages are available, see [Odata 4.01 spec](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_ServerDrivenPaging) for more details.\n\nClients MUST treat the `nextLink` URL as opaque, which means that query options may not be changed while iterating over a set of partial results.\n\nExample:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n  \"value\": [...],\n  \"@odata.nextLink\": \"{opaqueUrl}\"\n}\n```\n\n### 8.2. Client-driven paging\n\nClients MAY use _$top_ and _$skip_ query parameters to specify a number of results to return and an offset into the collection.\n\nThe server SHOULD honor the values specified by the client; however, clients MUST be prepared to handle responses that contain a different page size or contain a `@odata.nextLink` token.\n\nWhen both _$top_ and _$skip_ are given by a client, the server SHOULD first apply _$skip_ and then _$top_ on the collection.\n\nNote: If the server can't honor _$top_ and/or _$skip_, the server MUST return an error to the client informing about it instead of just ignoring the query options.\nThis will avoid the risk of the client making assumptions about the data returned.\n\nExample:\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$top=5&$skip=2 \n\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n   \"value\": [...]\n}\n```\n\n### 8.3. Additional considerations\n\n**Stable order prerequisite:** Both forms of paging depend on the collection of items having a stable order.\nThe server MUST supplement any specified order criteria with additional sorts (typically by key) to ensure that items are always ordered consistently.\n\n**Missing/repeated results:** Even if the server enforces a consistent sort order, results MAY be missing or repeated based on creation or deletion of other resources.\nClients MUST be prepared to deal with these discrepancies.\nThe server SHOULD always encode the record ID of the last read record, helping the client in the process of managing repeated/missing results.\n\n**Combining client- and server-driven paging:** Note that client-driven paging does not preclude server-driven paging.\nIf the page size requested by the client is larger than the default page size supported by the server, the expected response would be the number of results specified by the client, paginated as specified by the server paging settings.\n\n**Page Size:** Clients MAY request server-driven paging with a specific page size by specifying a _$maxpagesize_ preference.\nThe server SHOULD honor this preference if the specified page size is smaller than the server's default page size.\n\n**Paginating embedded collections:** It is possible for both client-driven paging and server-driven paging to be applied to embedded collections.\nIf a server paginates an embedded collection, it MUST include additional `nextLink` tokens as appropriate.\n\n**Recordset count:** Developers who want to know the full number of records across all pages, MAY include the query parameter _$count=true_ to tell the server to include the count of items in the response.\n\n## 9. Compound collection operations\n\nFiltering, Sorting and Pagination operations MAY all be performed against a given collection.\nWhen these operations are performed together, the evaluation order MUST be:\n\n1. **Filtering**. This includes all range expressions performed as an AND operation.\n2. **Sorting**. The potentially filtered list is sorted according to the sort criteria.\n3. **Pagination**. The materialized paginated view is presented over the filtered, sorted list. This applies to both server-driven pagination and client-driven pagination.\n\n## 10. Empty Results\n\nWhen a filter is performed on a collection and the result set is empty you MUST respond with a valid response body and a 200 response code.\nIn this example the filters supplied by the client resulted in a empty result set.\nThe response body is returned as normal and the _value_ attribute is set to a empty collection.\nYou SHOULD maintain consistency in your API whenever possible.\n\n```http\nGET https://graph.microsoft.com/beta/teamwork/devices?$filter=('deviceType'  eq 'Collab' or companyAssetTa eq 'Tag1')\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n   \"value\": []\n}\n```\n\n## 11. Collections of structural types (complex types or primitive types)\n\nEntity types are generally preferred for collections since complex types within a collection cannot be individually referenced. Collections of complex types, including any nested properties, must be updated as a single unit, entirely replacing the existing contents. Even if your API is read-only today, modeling it as a collection of entities gives you more flexibility in referencing individual members now and in the future. \nSometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types.\nTake the following model with an entity type `application` that has a collection of `keyCredential`s:\n\n```xml\n<EntityType Name=\"application\">\n  <Key>\n    <PropertyRef Name=\"id\" />\n  </Key>\n  <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n  <Property Name=\"keyCredentials\" Type=\"Collection(self.keyCredential)\" />\n  ...\n</EntityType>\n\n<ComplexType Name=\"keyCredential\">\n  <Property Name=\"keyId\" Type=\"Edm.Guid\" />\n  <Property Name=\"endDateTime\" Type=\"Edm.DateTimeOffset\" />\n  ...\n</ComplexType>\n```\nand a scenario arises that requires, for example, to remove individual `keyCredential`s from the collection. \nThere are two options forward:\n\n### 11.1 Side-by-side collection properties (for any collection of structural types)\n\nThe model can be updated to have two collections side-by-side, deprecating the existing one:\n```diff\n<EntityType Name=\"application\">\n  <Key>\n    <PropertyRef Name=\"id\" />\n  </Key>\n  <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n  <Property Name=\"keyCredentials\" Type=\"Collection(self.keyCredential)\">\n+   <Annotation Term=\"Org.OData.Core.V1.Revisions\">\n+     <Collection>\n+       <Record>\n+         <PropertyValue Property = \"Date\" Date=\"2020-08-20\"/>\n+         <PropertyValue Property = \"Version\" String=\"2020-08/KeyCredentials\"/>\n+         <PropertyValue Property = \"Kind\" EnumMember=\"Org.OData.Core.V1.RevisionKind/Deprecated\"/>\n+         <PropertyValue Property = \"Description\" String=\"keyCredentials has been deprecated. Please use keyCredentials_v2 instead.\"/>\n+         <PropertyValue Property = \"RemovalDate\" Date=\"2022-08-20\"/>\n+       </Record>\n+     </Collection>\n+   </Annotation>\n+ </Property>\n+ <NavigationProperty Name=\"keyCredentials_v2\" Type=\"Collection(self.keyCredential_v2)\" ContainsTarget=\"true\" />\n</EntityType>\n\n<ComplexType Name=\"keyCredential\">\n  <Property Name=\"keyId\" Type=\"Edm.Guid\" />\n  <Property Name=\"endDateTime\" Type=\"Edm.DateTimeOffset\" />\n</ComplexType>\n\n+<EntityType Name=\"keyCredential_v2\">\n+ <Key>\n+   <PropertyRef Name=\"keyId\" />\n+ </Key>\n+ <Property Name=\"keyId\" Type=\"Edm.Guid\" />\n+ <Property Name=\"endDateTime\" Type=\"Edm.DateTimeOffset\" />\n+</EntityType>\n```\nClients will now be able to refer to individual `keyCredential`s using `keyId` as a key, and they can now remove those `keyCredential`s using `DELETE` requests:\n```http\nDELETE /applications/{applicationId}/keyCredentials_v2/{some_keyId}\n```\n```http\nHTTP/1.1 204 No Content\n```\nWhile both properties exist on graph, the expectation is that `keyCredentials` and `keyCredentials_v2` are treated as two \"views\" into the same data.\nTo meet this expectation, workloads must:\n1. Keep the properties consistent between `keyCredential` and `keyCredential_v2`.\nAny changes to one type must be reflected in the other type.\n2. Reject requests that update both collections at the same time.\nA request that adds an item to `keyCredentials_v2` while replacing the content of `keyCredentials` must rejected with a `400`, for example:\n```http\nPATCH /applications/{applicationId}\n{\n  \"keyCredentials\": [\n    {\n      \"keyId\": \"10000000-0000-0000-0000-000000000000\",\n      \"endDateTime\": \"2012-12-03T07:16:23Z\"\n    }\n  ],\n  \"keyCredentials_v2@delta\": [\n    {\n      \"keyId\": \"20000000-0000-0000-0000-000000000000\",\n      \"endDateTime\": \"2012-12-03T07:16:23Z\"\n    }\n  ]\n}\n```\n```http\nHTTP/1.1 400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"'keyCredentials' and 'keyCredentials_v2' cannot be updated in the same request.\",\n}\n```\n\n### 11.2 Redefine as Entity Type (for collections of complex types)\n\nThe model can be updated to simply switch the complex type for an entity type:\n```diff\n<EntityType Name=\"application\">\n  <Key>\n    <PropertyRef Name=\"id\" />\n  </Key>\n  <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n- <Property Name=\"keyCredentials\" Type=\"Collection(self.keyCredential)\" />\n+ <NavigationProperty Name=\"keyCredentials\" Type=\"Collection(self.keyCredential)\" ContainsTarget=\"true\" />\n</EntityType>\n\n- <ComplexType Name=\"keyCredential\">\n+ <EntityType Name=\"keyCredential\">\n+ <Key>\n+   <PropertyRef Name=\"keyId\" />\n+ </Key>\n  <Property Name=\"keyId\" Type=\"Edm.Guid\" />\n  <Property Name=\"endDateTime\" Type=\"Edm.DateTimeOffset\" />\n-</ComplexType>\n+</EntityType>\n```\nTo maintain backwards compatibility **and** compliance with the OData standard, there are several semantic changes that the workload must address:\n1. Existing clients would have been able to `$select` the `keyCredentials` property.\nNow that `keyCredentials` is a navigation property, the [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361040) specifies that its navigation link be returned when it is `$selected`:\n\n> If the select item is a navigation property, then the corresponding navigation link is represented in the response.\n\nBecause the previous behavior for `$select=keyCredentials` was to include the collection in the response, and because the standard dictates that the navigation link be included in the response, the new behavior is to include both:\n\n```http\nGET /applications/{applicationId}?$select=keyCredentials\n```\n```http\n200 OK\n{\n  \"id\": \"{applicationId}\",\n  \"keyCredentials\": [\n    {\n      \"keyId\": \"30000000-0000-0000-0000-000000000000\",\n      \"endDateTime\": \"2012-12-03T07:16:23Z\",\n      ...\n    },\n    ...\n  ],\n  \"keyCredentials@odata.navigationLink\": \"/applications('{applicationId}')/keyCredentials\"\n}\n```\n\n2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `application` before, it must be preserved by **auto-expanding** the `keyCredentials` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).\n3. Structural collections can be updated using a `PATCH` request to the containing entity to replace the entire contents of the collection. If the service supported such updates to the structural collection, then updates to the new navigation property must preserve this behavior.\n"
  },
  {
    "path": "graph/articles/coreTypes.md",
    "content": "# Core Types\n\n## Overview\n\nTypes exist in Microsoft Graph which are highly-connected/central to the Microsoft Graph ecosystem. Often, these types are in the position of being able to contain structural properties relevant to other APIs, because they are connected to many entities in Microsoft Graph.\n\nStructural properties should be only added to these core types when they are intrinsic to the entity itself, and strictly not for the purpose of convenience due to the entity's position in Microsoft Graph.\n\n## Core Types in Microsoft Graph\n\nThe following types are identified as core types, and will require strong justification to allow new structural properties to be added in all cases.\n\n- ```user```\n- ```group```\n- ```device```\n\n## Alternatives to Adding Structural Properties\n\nInstead of adding a structural property to the existing core type (`user`, `group` or `device`), create a new type that models the information captured in the proposed structural property(s).\nThen, model the relationship between the existing core type and the new type by adding a navigation property. For information on modeling with navigation properties, see [Navigation Property](../patterns/navigation-property.md).\n\n## Example:\n\nModeling adding \"bank account information\", which includes two properties `accountNumber` and `routingNumber`, to entity type ```user```.\n\n### Don't:\n\nDon't add new properties to core types such as `user`.\n\n```xml\n<EntityType name=\"user\">\n    <Property Name=\"accountNumber\" Type=\"Edm.string\"/>\n    <Property Name=\"routingNumber\" Type=\"Edm.string\"/>\n</EntityType>\n```\n\n### Do:\n\nModel the information by creating a new type and model the relationship to the existing core type with a navigation property. To determine which option is most appropriate, see [Navigation Property](../patterns/navigation-property.md):\n\n#### Option 1: Add a navigation property on the existing core type to the new type, containing the new type.\n\nDefine the new entity type:\n```xml\n<EntityType name=\"bankAccountDetail\">\n    <Property Name=\"accountNumber\" Type=\"Edm.string\"/>\n    <Property Name=\"routingNumber\" Type=\"Edm.string\"/>\n</EntityType>\n```\n\nAdd a contained navigation from user to the new entity type:\n```xml\n<EntityType name=\"user\">\n    <NavigationProperty Name=\"bankAccountDetail\" Type=\"bankAccountDetail\" ContainsTarget=\"true\"/>\n</EntityType>\n```\n\n#### Option 2: Contain the new type in an entity set elsewhere, and add a navigation property to the new type on the existing core type.\n\nDefine the new entity type:\n```xml\n<EntityType name=\"bankAccountDetail\">\n    <Property Name=\"accountNumber\" Type=\"Edm.string\"/>\n    <Property Name=\"routingNumber\" Type=\"Edm.string\"/>\n</EntityType>\n```\n\nContain the new entity type in an entity set or singleton:\n```xml\n<EntitySet Name=\"bankAccountDetails\" EntityType=\"bankAccountDetail\">\n```\n\nAdd a navigation from user to the new type:\n```xml\n<EntityType name=\"user\">\n    <NavigationProperty Name=\"bankAccountDetail\" Type=\"bankAccountDetail\" />\n</EntityType>\n```\n\n#### Option 3: Contain the new type in an entity set elsewhere, and add a navigation property to the existing core type on the new type.\n\nDefine the new entity type, with a navigation to the user:\n```xml\n<EntityType name=\"bankAccountDetail\">\n    <Property Name=\"accountNumber\" Type=\"Edm.string\"/>\n    <Property Name=\"routingNumber\" Type=\"Edm.string\"/>\n    <NavigationProperty Name=\"user\" Type=\"microsoft.graph.user\" />\n</EntityType>\n```\n\nContain the new entity type in an entity set or singleton:\n```xml\n<EntitySet Name=\"bankAccountInformations\" EntityType=\"bankAccountInformation\">\n```\n"
  },
  {
    "path": "graph/articles/deprecation.md",
    "content": "# Deprecation guidelines\n\nIf your API requires the introduction of breaking changes, you must add Revisions annotations to the API definition with the following terms:\n\n- **Date:** Date when the element was marked as deprecated.\n- **Version:** Used to organize the ChangeLog. Use the format \"YYYY-MM/Category\", where \"YYYY-MM\" is the month the deprecation is announced, and \"Category\" is the category under which the change is described.\n- **Kind:** Deprecated\n- **Description:** Human readable description of the change. Used in ChangeLog, documentation, etc.\n- **RemovalDate:** Earliest date when the element can be removed.\n\nThe annotation can be applied to a type, an entity set, a singleton, a property, a\nnavigation property, a function, or an action. If a type is marked as deprecated, it\nis not necessary to mark the members of that type as deprecated, nor is it necessary\nto annotate any usages of that type.\n\n## Example of property annotation\n\n```xml\n<EntityType Name=\"outlookTask\" BaseType=\"Microsoft.OutlookServices.outlookItem\" ags:IsMaster=\"true\" ags:WorkloadName=\"Task\" ags:EnabledForPassthrough=\"true\">\n  <Annotation Term=\"Org.OData.Core.V1.Revisions\">\n    <Collection>\n      <Record>\n        <PropertyValue Property = \"Date\" Date=\"2022-03-30\"/>\n        <PropertyValue Property = \"Version\" String=\"2022-03/Tasks_And_Plans\"/>\n        <PropertyValue Property = \"Kind\" EnumMember=\"Org.OData.Core.V1.RevisionKind/Deprecated\"/>\n        <PropertyValue Property = \"Description\" String=\"The Outlook tasks API is deprecated and will stop returning data on June 30, 2024. Please use the new To Do API.\"/>\n        <PropertyValue Property = \"RemovalDate\" Date=\"2024-06-30\"/>\n      </Record>\n    </Collection>\n  </Annotation>\n</EntityType>\n```\n\nWhen the request URL contains a reference to a deprecated model element, the gateway adds a [Deprecation header](https://tools.ietf.org/html/draft-dalal-deprecation-header-02) (with the date the element was marked as deprecated) and a Sunset header (with the date of two years beyond the deprecation date) to the response.\n\n## Deprecation header example\n\n```\n Deprecation: Wed, 30 Mar 2022 11:59:59 GMT\n Sunset:  Thursday, 30 June 2024 23:59:59 GMT\n Link: https://docs.microsoft.com/en-us/graph/changelog#2022-03-30_name ; rel=\"deprecation\"; type=\"text/html\"; title=\"name\",https://docs.microsoft.com/en-us/graph/changelog#2022-03-30_state ; rel=\"deprecation\"; type=\"text/html\"; title=\"state\"\n\n```\n"
  },
  {
    "path": "graph/articles/errorResponses.md",
    "content": "# Error condition responses\n\nFor non-success conditions, developers SHOULD be able to write one piece of code that handles errors consistently across different Microsoft REST API services.\nThis allows building of simple and reliable infrastructure to handle exceptions as a separate flow from successful responses.\nThe following is based on the OData v4 JSON spec.\nHowever, it is very generic and does not require specific OData constructs.\nAPIs SHOULD use this format even if they are not using other OData constructs.\n\nThe error response MUST be a single JSON object.\nThis object MUST have a name/value pair named \"error\". The value MUST be a JSON object.\n\nThis object MUST contain name/value pairs with the names \"code\" and \"message\", and it MAY contain name/value pairs with the names \"target\", \"details\" and \"innererror.\"\n\nThe value for the \"code\" name/value pair is a language-independent string and MUST match the HTTP response status code description, converted to camelCase, as listed in the [Status Code Registry (iana.org)](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml)\nFor example, if the HTTP status code is \"Not Found\", then the \"code\" value MUST be \"notFound\".\n\nMost services will require a larger number of more specific error codes, which are not interesting to all clients.\nThese error codes SHOULD be exposed in the \"innererror\" name/value pair as described below.\nIntroducing a new value for \"code\" that is visible to existing clients is a breaking change and requires a version increase.\nServices can avoid breaking changes by adding new error codes to \"innererror\" instead.\n\nThe value for the \"message\" name/value pair MUST be a human-readable representation of the error.\nIt is intended as an aid to developers and is not suitable for exposure to end users.\nServices wanting to expose a suitable message for end users MUST do so through an [odata-json-annotations](https://docs.oasis-open.org/odata/odata-json-format/v4.01/cs02/odata-json-format-v4.01-cs02.html#sec_AnnotateaJSONObject) or custom property.\nServices SHOULD NOT localize \"message\" for the end user, because doing so might make the value unreadable to the app developer who may be logging the value, as well as make the value less searchable on the Internet.\n\nThe value for the \"target\" name/value pair is the target of the particular error (e.g., the name of the property in error).\n\nThe value for the \"details\" name/value pair MUST be an array of JSON objects that MUST contain name/value pairs for \"code\" and \"message\", and MAY contain a name/value pair for \"target\", as described above.\nThe objects in the \"details\" array usually represent distinct, related errors that occurred during the request.\nSee example below.\n\nThe value for the \"innererror\" name/value pair MUST be an object.\nThe contents of this object are service-defined.\nServices wanting to return more specific errors than the root-level code MUST do so by including a name/value pair for \"code\" and a nested \"innererror\". Each nested \"innererror\" object represents a higher level of detail than its parent.\nWhen evaluating errors, clients MUST traverse through all of the nested \"innererrors\" and choose the deepest one that they understand.\nThis scheme allows services to introduce new error codes anywhere in the hierarchy without breaking backwards compatibility, so long as old error codes still appear.\nThe service MAY return different levels of depth and detail to different callers.\nFor example, in development environments, the deepest \"innererror\" MAY contain internal information that can help debug the service.\nTo guard against potential security concerns around information disclosure, services SHOULD take care not to expose too much detail unintentionally.\nError objects MAY also include custom server-defined name/value pairs that MAY be specific to the code.\nError types with custom server-defined properties SHOULD be declared in the service's metadata document.\nSee example below.\n\nError responses MAY contain Odata JSON annotations in any of their JSON objects.\n\nWe recommend that for any transient errors that may be retried, services SHOULD include a Retry-After HTTP header indicating the minimum number of seconds that clients SHOULD wait before attempting the operation again.\n\n## ErrorResponse : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`error` | Error | ✔ | The error object.\n\n## Error : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`code` | String | ✔ | One of a server-defined set of error codes.\n`message` | String | ✔ | A human-readable representation of the error.\n`target` | String |  | The target of the error.\n`details` | Error[] |  | An array of details about specific errors that led to this reported error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n\n## InnerError : Object\n\nProperty | Type | Required | Description\n-------- | ---- | -------- | -----------\n`code` | String |  | A more specific error code than was provided by the containing error.\n`innererror` | InnerError |  | An object containing more specific information than the current object about the error.\n\n## Examples\n\nExample of \"innererror\":\n\n```json\n{\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"Previous passwords may not be reused\",\n    \"target\": \"password\",\n    \"innererror\": {\n      \"code\": \"passwordError\",\n      \"innererror\": {\n        \"code\": \"passwordDoesNotMeetPolicy\",\n        \"minLength\": \"6\",\n        \"maxLength\": \"64\",\n        \"characterTypes\": [\"lowerCase\",\"upperCase\",\"number\",\"symbol\"],\n        \"minDistinctCharacterTypes\": \"2\",\n        \"innererror\": {\n          \"code\": \"passwordReuseNotAllowed\"\n        }\n      }\n    }\n  }\n}\n```\n\nIn this example, the most basic error code is \"unauthorized\", but for clients that are interested, there are more specific error codes in \"innererror.\"\nThe \"passwordReuseNotAllowed\" code may have been added by the service at a later date, having previously only returned \"passwordDoesNotMeetPolicy.\"\nExisting clients do not break when the new error code is added, but new clients MAY take advantage of it.\nThe \"passwordDoesNotMeetPolicy\" error also includes additional name/value pairs that allow the client to determine the server's configuration, validate the user's input programmatically, or present the server's constraints to the user within the client's own localized messaging.\n\nExample of \"details\":\n\n```json\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"Multiple errors in ContactInfo data\",\n    \"target\": \"contactInfo\",\n    \"details\": [\n      {\n        \"code\": \"nullValue\",\n        \"target\": \"phoneNumber\",\n        \"message\": \"Phone number must not be null\"\n      },\n      {\n        \"code\": \"nullValue\",\n        \"target\": \"lastName\",\n        \"message\": \"Last name must not be null\"\n      },\n      {\n        \"code\": \"malformedValue\",\n        \"target\": \"address\",\n        \"message\": \"Address is not valid\"\n      }\n    ]\n  }\n}\n```\n\nIn this example there were multiple problems with the request, with each individual error listed in \"details.\"\n"
  },
  {
    "path": "graph/articles/filter-as-segment.md",
    "content": "# Filter as segment\n\nThere is an [OData feature](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_AddressingaSubsetofaCollection) which allows having a `$filter` in a URL segment. \nThis feature is useful whenever there are operations on a collection and the client wants to perform those operations on a *subset* of the collection. \nFor example, the `riskyUsers` API on Microsoft Graph has an action defined to let clients \"dismiss\" risky users (i.e. consider those users \"not risky\"):\n\n```xml\n<Action Name=\"dismiss\" IsBound=\"true\">\n  <Parameter Name=\"bindingParameter\" Type=\"Collection(microsoft.graph.riskyUser)\" />\n  <Parameter Name=\"userIds\" Type=\"Collection(Edm.String)\" />\n</Action>\n```\n\nUsing this action, clients can call\n\n```http\nPOST /identityProtection/riskyUsers/dismiss\n{\n  \"userIds\": [\n    \"{userId1}\",\n    \"{userId2}\",\n    ...\n  ]\n}\n```\n\nin order to dismiss the risky users with the provided IDs. Using the filter-as-segment OData feature, the action could instead be defined as:\n\n```xml\n<Action Name=\"dismiss\" IsBound=\"true\">\n  <Parameter Name=\"bindingParameter\" Type=\"Collection(self.riskyUser)\" />\n</Action>\n```\n\nand clients could call\n\n```http\nPOST /identityProtection/riskyUsers/$filter=@f/dismiss?@f=id IN ('{userId1}','{userId2}',...)\n```\n\nDoing this is beneficial due to the robust nature of OData filter expressions: clients will be able to dismiss risky users based on any supported filter without the service team needing to implement a new `dismiss` overload that filters based on the new criteria.\nHowever, there are some concerns about the discoverability of using the filter-as-segment feature, as well as the support of [parameter aliasing](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_ParameterAliases) that's required.\nAs a result, functions should be introduced that act in the same way as the filter-as-segment:\n\n```xml\n<Function Name=\"filter\" IsBound=\"true\" IsComposable=\"true\">\n  <Parameter Name=\"bindingParameter\" Type=\"Collection(microsoft.graph.riskyUser)\" Nullable=\"false\" />\n  <Parameter Name=\"expression\" Type=\"Edm.String\" Nullable=\"false\" />\n  <ReturnType Type=\"Collection(microsoft.graph.riskyUser)\" />\n</Function>\n```\n\nClients would now be able to call\n\n```http\nPOST /identityProtection/riskyUsers/filter(expression='id IN (''{userId1}'',''{userId2}'',...)')/dismiss\n```\n\nNOTE: the `'` literal in the filter expression must be escaped with `''`\n\nAn example implementation of a filter function using OData WebApi can be found [here](https://github.com/OData/AspNetCoreOData/commit/7732f7e6b812d9a79a73529562f2e74b68e2794f).\n"
  },
  {
    "path": "graph/articles/naming.md",
    "content": "# Naming\n\n## 1. Approach\n\nNaming policies should aid developers in discovering functionality without having to constantly refer to documentation.\nUse of common patterns and standard conventions greatly aids developers in correctly guessing common property names and meanings.\nServices SHOULD use verbose naming patterns and MUST NOT use abbreviations other than acronyms that are the dominant mode of expression in the domain being represented by the API, (e.g. Url).\n\n## 2. Casing\n\n- Acronyms SHOULD follow the casing conventions as though they were regular words (e.g. Url).\n- All identifiers including namespaces, entityTypes, entitySets, properties, actions, functions and enumeration values MUST use lowerCamelCase.\n- HTTP headers are the exception and SHOULD use standard HTTP convention of Capitalized-Hyphenated-Terms.\n\n## 3. Names to avoid\n\nCertain names are so overloaded in API domains that they lose all meaning or clash with other common usages in domains that cannot be avoided when using REST APIs, such as OAUTH.\nServices SHOULD NOT use the following names:\n\n- Context\n- Scope\n- Resource\n\n## 4. Forming compound names\n\n- Services SHOULD avoid using articles such as 'a', 'the', 'of' unless needed to convey meaning.\n  - e.g. names such as aUser, theAccount, countOfBooks SHOULD NOT be used, rather user, account, bookCount SHOULD be preferred.\n- Services SHOULD add a type to a property name when not doing so would cause ambiguity about how the data is represented or would cause the service not to use a common property name.\n- When adding a type to a property name, services MUST add the type at the end, e.g. createdDateTime.\n\n## 5. Identity properties\n\n- Services MUST use string types for identity properties.\n- For OData services, the service MUST use the OData @id property to represent the canonical identifier of the resource.\n- Services MAY use the simple 'id' property to represent a local or legacy primary key value for a resource.\n- Services SHOULD use the name of the relationship postfixed with 'Id' to represent a foreign key to another resource, e.g. subscriptionId.\n  - The content of this property SHOULD be the canonical ID of the referenced resource.\n\n## 6. Date and time properties\n\n- For properties requiring both date and time, services MUST use the suffix 'DateTime'.\n- For properties requiring only date information without specifying time, services MUST use the suffix 'Date', e.g. birthDate.\n- For properties requiring only time information without specifying date, services MUST use the suffix 'Time', e.g. appointmentStartTime.\n\n## 7. Name properties\n\n- For the overall name of a resource typically shown to users, services MUST use the property name 'displayName'.\n- Services MAY use other common naming properties, e.g. givenName, surname, signInName.\n\n## 8. Collections and counts\n\n- Services MUST name collections as plural nouns or plural noun phrases using correct English.\n- Services MAY use simplified English for nouns that have plurals not in common verbal usage.\n  - e.g. schemas MAY be used instead of schemata.\n- Services MUST name counts of resources with a noun or noun phrase suffixed with 'Count'.\n\n## 9. Common property names\n\nWhere services have a property, whose data matches the names below, the service MUST use the name from this table.\nThis table will grow as services add terms that will be more commonly used.\nService owners adding such terms SHOULD propose additions to this document.\n\n|                     |   |\n|-------------------- | - |\n attendees            |\n body                 |\n completedDateTime    | **NOTE** completionDateTime may be used for cases where the timestamp represents a point in the future |\n createdDateTime      |\n childCount           |\n children             |\n contentUrl           |\n country              |\n createdBy            |\n displayName          |\n errorUrl             |\n eTag                 |\n event                |\n expirationDateTime   |\n givenName            |\n jobTitle             |\n kind                 |\n id                   |\n lastModifiedDateTime |\n location             |\n memberOf             |\n message              |\n name                 |\n owner                |\n people               |\n person               |\n postalCode           |\n photo                |\n preferredLanguage    |\n properties           |\n signInName           |\n surname              |\n tags                 |\n userPrincipalName    |\n webUrl               |\n"
  },
  {
    "path": "graph/articles/nullable.md",
    "content": "# Nullable Properties\n\nA nullable property means *only* that the property may have `null` as a value; the \"nullability\" of a property does not say anything about how a value is set into a property.\nFor example, a non-nullable property is *not* required to create a new instance of an entity.\nIt only means that the property will have a value when it is retrieved.\nIn the case that no value is provided when the entity is created, this means that the service will create one; this value can be specified with the `DefaultValue` attribute, but if the value is contextual and determine at request time, then the property can both be non-nullable *and* have no `DefaultValue` specified. \nBelow are some examples of nullable and non-nullable properties. \n\n## CSDL\n\n```xml\n<EntitySet Name=\"servicePrincipals\" Type=\"self.servicePrincipal\" />\n...\n<EntityType Name=\"servicePrincipal\">\n  <Key>\n    <PropertyRef Name=\"id\" />\n  </Key>\n  <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n  <Property Name=\"appId\" Type=\"Edm.String\" Nullable=\"false\" /> <!--required for creation-->\n  <Property Name=\"displayName\" Type=\"Edm.String\" Nullable=\"false\" />\n  <Property Name=\"foo\" Type=\"Edm.String\" Nullable=\"true\" DefaultValue=\"testval\" />\n  <Property Name=\"bar\" Type=\"Edm.String\" Nullable=\"false\" DefaultValue=\"differentvalue\" />\n  ...\n</EntityType>\n```\n\n## HTTP Requests\n\n### 1. Create a servicePrincipal with no properties\n\n```HTTP\nPOST /servicePrincipals\n\n400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"The 'appId' property is required to create a servicePrincipal.\"\n  }\n}\n```\n\n### 2. Create a servicePrincipal without a display name\n\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\"\n}\n\n201 Created\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"some application name\",\n  \"foo\": \"testval\",\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `displayName` was given a value by the service even though no value was provided by the client\n2. `foo` has the default value as specified by its `DefaultValue` attribute in the CSDL\n3. `bar` has the default value as specified by its `DefaultValue` attribute in the CSDL\n\n### 3. Update the display name of a service principal to null\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"displayName\": null\n}\n\n400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"null is not a valid value for the property 'displayName'; 'displayName' is not a nullable property.\"\n  }\n}\n```\nNotes:\n1. `displayName` cannot be set to `null` because it has be marked with `Nullable=\"false\"` in the CSDL.\n\n### 4. Update the display name of a service principal\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"displayName\": \"a non-generated display name\"\n}\n\n200 OK\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a non-generated display name\",\n  \"foo\": \"testval\",\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `displayName` can be set to any value other than `null`\n2. The response body here is provided for clarity, and is not part of the guidance itself. The [OData v4.01 standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) states that the workload can decide the behavior.\n\n### 5. Update the foo property of a service principal to null\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"foo\": null\n}\n\n200 OK\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a non-generated display name\",\n  \"foo\": null,\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `foo` can be set to `null` because it has be marked with `Nullable=\"true\"` in the CSDL.\n2. The response body here is provided for clarity, and is not part of the guidance itself. The [OData v4.01 standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) states that the workload can decide the behavior.\n\n### 6. Update the foo property of a service principal to a non-default value\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"foo\": \"something other than testval\"\n}\n\n200 OK\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a non-generated display name\",\n  \"foo\": \"something other than testval\",\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `foo` can be set to `something other than testval`\n2. The response body here is provided for clarity, and is not part of the guidance itself. The [OData v4.01 standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) states that the workload can decide the behavior.\n\n### 7. Update the bar property of a service principal to null\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"bar\": null\n}\n\n400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"null is not a valid value for the property 'bar'; 'bar' is not a nullable property.\"\n  }\n}\n```\nNotes:\n1. `bar` cannot be set to `null` because it has be marked with `Nullable=\"false\"` in the CSDL.\n\n### 8. Update the bar property of a service principal to a non-default value\n\n```HTTP\nPATCH /servicePrincipals/00000000-0000-0000-0000-000000000001\n{\n  \"bar\": \"a new bar\"\n}\n\n200 OK\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a non-generated display name\",\n  \"foo\": \"something other than testval\",\n  \"bar\": \"a new bar\",\n  ...\n}\n```\nNotes:\n1. `bar` can be set to `a new bar`\n2. The response body here is provided for clarity, and is not part of the guidance itself. The [OData v4.01 standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) states that the workload can decide the behavior.\n\n### 9. Create a service principal while customizing the display name\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a different name\"\n}\n\n201 Created\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"a different name\",\n  \"foo\": \"testval\",\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `displayName` isn't required to create a new `servicePrincipal`, but it *can* be provided; this is orthogonal to whether or not the property has `Nullable=\"true\"` or `Nullable=\"false\"`.\n2. `foo` has the default value as specified by its `DefaultValue` attribute in the CSDL\n3. `bar` has the default value as specified by its `DefaultValue` attribute in the CSDL\n\n### 10. Create a service principal with a null display name\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": null\n}\n\n400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"null is not a valid value for the property 'displayName'; 'displayName' is not a nullable property.\"\n  }\n}\n```\nNotes:\n1. `displayName` isn't required to create a new `servicePrincipal`, but it *can* be provided; it *cannot* be provided as `null` because the property was marked with `Nullable=\"false\"`\n\n### 11. Create a service principal with a value for the foo property\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"foo\": \"a foo value on creation\"\n}\n\n201 Created\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"some application name\",\n  \"foo\": \"a foo value on creation\",\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `displayName` was given a value by the service even though no value was provided by the client\n2. `foo` isn't required to create a new `servicePrincipal`, but it *can* be provided; this is orthogonal to whether or not the property has `Nullable=\"true\"` or `Nullable=\"false\"`.\n3. `bar` has the default value as specified by its `DefaultValue` attribute in the CSDL\n\n### 12. Create a service principal with null for the foo property\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"foo\": null\n}\n\n201 Created\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"some application name\",\n  \"foo\": null,\n  \"bar\": \"differentvalue\",\n  ...\n}\n```\nNotes:\n1. `displayName` was given a value by the service even though no value was provided by the client\n2. `foo` isn't required to create a new `servicePrincipal`, but it *can* be provided; because the property has `Nullable=\"true\"`, a `null` value can be provided for it.\n3. `bar` has the default value as specified by its `DefaultValue` attribute in the CSDL\n\n### 13. Create a service principal with a value for the bar property\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"bar\": \"running out of ideas for value names\"\n}\n\n201 Created\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"displayName\": \"some application name\",\n  \"foo\": \"testval\",\n  \"bar\": \"running out of ideas for value names\",\n  ...\n}\n```\nNotes:\n1. `displayName` was given a value by the service even though no value was provided by the client\n2. `foo` has the default value as specified by its `DefaultValue` attribute in the CSDL\n3. `bar` isn't required to create a new `servicePrincipal`, but it *can* be provided; this is orthogonal to whether or not the property has `Nullable=\"true\"` or `Nullable=\"false\"`.\n\n### 14. Create a service principal with null for the bar property\n```HTTP\nPOST /servicePrincipals\n{\n  \"appId\": \"00000000-0000-0000-0000-000000000001\",\n  \"bar\": null\n}\n\n400 Bad Request\n{\n  \"error\": {\n    \"code\": \"badRequest\",\n    \"message\": \"null is not a valid value for the property 'bar'; 'bar' is not a nullable property.\"\n  }\n}\n```\nNotes:\n1. `bar` isn't required to create a new `servicePrincipal`, but it *can* be provided; it *cannot* be provided as `null` because the property was marked with `Nullable=\"false\"`\n"
  },
  {
    "path": "graph/patterns/PatternDescriptionTemplate.md",
    "content": "# Pattern name\n\nMicrosoft Graph API Design Pattern\n\n*Provide a short description of the pattern.*\n\n\n## Problem\n\n*Describe the business context relevant for the pattern.*\n\n*Provide a short description of the problem.*\n\n## Solution\n\n*Describe how to implement the solution to solve the problem.*\n\n*Describe related patterns.*\n\n## When to use this pattern\n\n*Describe when and why the solution is applicable and when it might not be.*\n\n## Issues and considerations\n\n*Describe tradeoffs of the solution.*\n\n## Example\n\n*Provide a short example from real life.*\n"
  },
  {
    "path": "graph/patterns/alternate-key.md",
    "content": "# Alternate key\n\nMicrosoft Graph API Design Pattern\n\n*The alternate key pattern provides the ability to query for a single, specific resource identifiable via one of an alternative set of properties that is not its primary key.*\n\n## Problem\n\nThe resources exposed in Microsoft Graph are identified through a primary key, which guarantees uniqueness inside the same resource collection. Often though, that same resource can also be uniquely identified by an alternative, more convenient property that provides a better developer experience.\n\nTake a look at the `user` resource: while the `id` is the typical way to get the resource details, the `mail` address is also a unique property that can be used to identify it.\n\nThe resource can be accessed using the `$filter` query parameter, such as\n\n```http\nGET https://graph.microsoft.com/v1.0/users?$filter=mail eq 'bob@contoso.com'\n```\nHowever, in this case, the returned result is wrapped in an array that needs to be unpacked. When the uniqueness of the property within the collection implies that only zero or one results can be returned from the call this array provides a suboptimal experience for callers.\n\n## Solution\n\nTypically resources in Graph are accessed using a simple forward-slash delimited URL pattern (this pattern is sometimes referred to as key-as-segment).\n\n```http\nhttps://graph.microsoft.com/v1.0/users/0 - Retrieves the employee with ID = 0.\n```\n\nHowever, resources can also be accessed using parentheses to delimit the key, like this:\n\n```http\nhttps://graph.microsoft.com/v1.0/users(0) - Also retrieves the employee with ID = 0.\n```\n\nResource addressing by using an alternative key can be achieved by using this same parentheses-style convention with one difference: alternate keys MUST specify the key property name to unambiguously determine the alternate key, like this:\n\n```http\nhttps://graph.microsoft.com/v1.0/users(email='bob@contoso.com') Retrieves the employee with the email matching `bob@contoso.com`.\n```\n\nIn the same way as requesting a resource via the canonical key, if a resource cannot be located that matches the alternate key, then a 404 must be returned.\n\n> **Note:** When requesting a resource via alternate keys, the simple slash-delimited URL style does not work.\n\n> **Note:** Do not use multi-part alternate keys.   Feedback has been that customers find multi-part keys confusing.\n> Either create a composite single-part surrogate key property or fall back to logical operations in a $filter clause.\n\n## When to use this pattern\n\nUse this pattern when your resource type has other keys than its canonical key which uniquely identify a single resource.\n\n## Example\n\nThe same user is identified via the alternate key SSN, the canonical (primary) key ID using the non-canonical long form with a specified key property name, and the canonical short form without a key property name.\n\nDeclare `mail` and `ssn` as alternate keys on an entity:\n\n```xml\n<EntityType Name=\"user\">\n   <Key>\n     <PropertyRef Name=\"id\" />\n   </Key>\n   <Property Name=\"id\" Type=\"Edm.Int32\" />\n\n   <Property Name=\"mail\" Type=\"Edm.String\" />\n   <Property Name=\"ssn\" Type=\"Edm.String\" />\n   <Annotation Term=\"OData.Community.Keys.V1.AlternateKeys\">\n      <Collection>\n         <Record Type=\"OData.Community.Keys.V1.AlternateKey\">\n            <PropertyValue Property=\"Key\">\n               <Collection>\n                  <Record Type=\"OData.Community.Keys.V1.PropertyRef\">\n                     <PropertyValue Property=\"Name\" PropertyPath=\"mail\" />\n                  </Record>\n               </Collection>\n            </PropertyValue>\n         </Record>\n         <Record Type=\"OData.Community.Keys.V1.AlternateKey\">\n            <PropertyValue Property=\"Key\">\n               <Collection>\n                  <Record Type=\"OData.Community.Keys.V1.PropertyRef\">\n                     <PropertyValue Property=\"Name\" PropertyPath=\"ssn\" />\n                  </Record>\n               </Collection>\n            </PropertyValue>\n         </Record>\n      </Collection>\n   </Annotation>\n</EntityType>\n```\n\n1. Get a specific resource through `$filter`:\n\n    ```http\n    GET https://graph.microsoft.com/v1.0/users/?$filter=ssn eq '123-45-6789'\n    ```\n    \n    ```json\n    {\n      \"value\": [\n        {\n          \"givenName\": \"Bob\",\n          \"jobTitle\": \"Retail Manager\",\n          \"mail\": \"bob@contoso.com\",\n          \"mobilePhone\": \"+1 425 555 0109\",\n          \"officeLocation\": \"18/2111\",\n          \"preferredLanguage\": \"en-US\",\n          \"ssn\": \"123-45-6789\",\n          \"surname\": \"Vance\",\n          \"userPrincipalName\": \"bob@contoso.com\",\n          \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\"\n        }\n      ]\n    }\n    ```\n\n2. Get a specific resource either through its primary key or through the two alternate keys:\n\n    ```http\n    GET https://graph.microsoft.com/v1.0/users/1a89ade6-9f59-4fea-a139-23f84e3aef66\n    GET https://graph.microsoft.com/v1.0/users(1a89ade6-9f59-4fea-a139-23f84e3aef66)\n    GET https://graph.microsoft.com/v1.0/users(ssn='123-45-6789')\n    GET https://graph.microsoft.com/v1.0/users(mail='bob@contoso.com')\n    ```\n   \n    All four yield the same response:\n    \n    ```json\n    {\n      \"givenName\": \"Bob\",\n      \"jobTitle\": \"Retail Manager\",\n      \"mail\": \"bob@contoso.com\",\n      \"mobilePhone\": \"+1 425 555 0109\",\n      \"officeLocation\": \"18/2111\",\n      \"preferredLanguage\": \"en-US\",\n      \"ssn\": \"123-45-6789\",\n      \"surname\": \"Vance\",\n      \"userPrincipalName\": \"bob@contoso.com\",\n      \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\"\n    }\n    ```\n\n3. Request a resource for an unsupported alternate key property:\n\n    ```http\n    GET https://graph.microsoft.com/v1.0/users(name='Bob')\n    \n    400 Bad Request\n    {\n        \"error\" : {\n            \"code\" : \"400\",\n            \"message\": \"'name' is not a valid alternate key for the resource type 'user'.\"\n        }\n    }\n    ```\n\n4. Request a resource where the alternate key property does not exist on any resource in the collection:\n\n    ```http\n    GET https://graph.microsoft.com/v1.0/users(email='unknown@contoso.com')\n    \n    404 Not Found\n    {\n        \"error\" : {\n            \"code\" : \"404\",\n            \"message\": \"No user with the the specified 'email' could be found.\"\n        }\n    }\n    ```\n"
  },
  {
    "path": "graph/patterns/antiPatternTemplate.md",
    "content": "\n# Antipattern name\n\n*name with a negative connotation*\n\n*Example: Flatbag of properties* \n\n## Description\n\n*Example: The flat bag pattern is a known anti-pattern in Microsoft Graph, where multiple variants of a common concept are modeled as a single entity type with all potential properties plus an additional property to distinguish the variants.*  \n\n## Consequences\n*Describe the consequences in terms of the developer experience*\n\n*Example: This is the least recommended modeling choice because it is weakly typed, which increases the number of variations and complexity of solutions, making it difficult to verify the semantic correctness of the API for both clients and producers...* \n\n## Preferable solutions \n\n*Example: It is preferable to use type hierarchy and facets patterns.\nShould provide a link to a valid pattern or patterns.* \n\n## Example\n\n*Provide an example of better modeling*\n"
  },
  {
    "path": "graph/patterns/change-tracking.md",
    "content": "# Change tracking\n\nMicrosoft Graph API Design Pattern\n\n*The change tracking pattern provides the ability for API consumers to request changes in data from Microsoft Graph without having to re-read data that has not changed.*\n\n\n## Problem\n\nAPI consumers require an efficient way to acquire changes to data in the Microsoft Graph, for example to synchronize an external store or to drive a change-centric business process.\n\n## Solution\n\nAPI designers can enable the change tracking (delta) capability on a resource in the Microsoft Graph (typically on an entity collection or a parent resource) by declaring a delta function on that resource and applying `Org.OData.Capabilities.V1.ChangeTracking` annotation.\n\nThis function returns a delta payload. A delta payload consists of a collection of annotated full or partial Microsoft Graph entities plus either a `nextLink` to further pages of original or change data that are immediately available OR a `deltaLink` to get the next set of changes at some later date.\n\nThe `nextLink` provides a mechanism to do server-driven paging through the change data that is currently available.  When there are no further pages of changes immediately available, a `deltaLink` is returned instead.\nThe `deltaLink` provides a mechanism for the API consumer to catch up on changes since their last request to the delta function. If no changes have happened since the last request, then the deltaLink MUST return an empty collection.\n\nBoth `nextLink` and `deltaLink` MUST be considered opaque URLs. The best practice is to make them opaque via encoding.\n\nThe pattern requires a sequence of requests on the delta function, for additional details see [Change Tracking](https://learn.microsoft.com/en-us/graph/delta-query-overview?tabs=http#use-delta-query-to-track-changes-in-a-resource-collection):\n\n  1. GET request which returns the first page of the current state of the resources that delta applies to.  \n  2. [Optionally] Further GET requests to retrieve more pages of the current state via the `@odata.nextLink` URL.\n  3. After some time, a GET request to see if there are new changes via the `@odata.deltaLink` URL.\n  4. [Optionally] GET requests to retrieve more pages of changes via the `@odata.nextLink` URL.\n\nDelta payload requirements:\n  - The payload is a collection of change records using the collection format.\n  - The change records are full or partial representations of the resources according to their resource types.\n  - When a change representing a resource update is included in the payload the API producer MAY return either the changed properties or the full entity. The ID of the resource MUST be included in every change record.\n  - When an entity is deleted, the delta function MUST return the ID of the deleted entity as well as an `@removed` annotation with the reason field.\n  - When an entity is deleted, the reason MUST be set to “changed” if the entity can be restored.\n  - When an entity is deleted. the reason MUST be set to “deleted” if the entity cannot be restored.\n  - There is no mechanism to indicate that a resource has entered or exited the dataset based on a change that causes it to match or no longer match any `$filter` query parameter.\n  - When a link to an entity is deleted, when the linked entity is deleted, or when a link to an entity is added, the implementer MUST return a `property@delta` annotation. \n  - When a link to an entity is deleted, but the entity still exists, the reason MUST be set to `changed`.\n  - When a link to an entity is deleted along with the entity, the reason MUST be set to `deleted`.\n\nAPI producers MAY choose to collate multiple changes to the same resource into a single change record. \n\nAPI consumers are expected to differentiate resource adds from updates by interpreting the id property of the change records against the existence of resources in whatever external system is doing the processing.\n\n\n## When to use this pattern\n\nAPI consumers want a pull mechanism to request and process change to Microsoft Graph data, either via proactive polling or by responding to Microsoft Graph notifications.\n\nAPI consumers need guaranteed data integrity over the set of changes to Microsoft Graph data.\n\n## Considerations\n\n - API service MAY be able to respond to standard OData query parameters with the initial call to the delta function:\n\n    - `$select` to enforce the set of properties on which change is reported.\n    - `$filter` to influence the scope of changes returned.\n    - `$expand` to include linked resources with the set of changes.\n    - `$top` parameter to influence the size of the set of change records.\n  \n    These query parameters MUST be encoded into subsequent `@odata.nextLink` or `@odata.deltaLink`, such that the same options are preserved through the call sequence without callers respecifying them, which MUST NOT be allowed. OData query parameters must be honored in full, or a 400-error returned.\n- Making a sequence of calls to a delta function followed by the opaque URLs in the `nextLink` and `deltaLink` MUST guarantee that the data at the start time of the call sequence and all changes to the data thereafter will be returned at least once. It is not necessary to avoid duplicates in the sequence. When the delta function is returning changes, they MUST be sequenced chronologically refer to [public documentation](https://learn.microsoft.com/en-us/graph/delta-query-overview?view=graph-rest-1.0) for more details.\n- The delta function can be bound to\n  - an entity collection, as with `/users/delta` that returns the changes to the users' collection, or\n  - some logical parent resource that returns an entity collection, where the change records are implied to be relative to all collections contained within the parent.For example  `/me/planner/all/delta` returns changes to any resource within a planner, which are referenced by 'all' navigation property, and `/communications/onlineMeetings/getAllRecordings/delta` returns changes to any meeting recordings returned by `getAllRecordings` function.\n\n- API service should use `$skipToken` and `$deltaToken` within their implementations of `nextLink` and `deltaLink`, however the URLs are defined as being opaque and the existence of the tokens MUST NOT be documented.   It is not a breaking change to modify the structure of `nextLinks` or `deltaLinks`.- \n- `nextLink` and `deltaLink` URLs are valid for a specific period before the client application needs to run a full synchronization again.For `nextLink`, a minimal validity time should be 1 hour. For `deltaLink`, a minimal validity time should be seven days. When a link is no longer valid it must return a standard error with a 410 GONE response code.\n- Although this capability is similar to the OData `$delta` feed capability, it is a different construct. Microsoft Graph APIs MUST provide change tracking through the delta function and MUST NOT implement the OData `$delta` feed when providing change tracking capabilities to ensure the uniformity of the API experience.\n- The Graph delta payload format has some deviations from the OData 4.01 change tracking format to simplify parsing, for example the context annotation is removed.\n- Additional implementation details are documented [internally](https://dev.azure.com/msazure/One/_wiki/wikis/Microsoft%20Graph%20Partners/211718/Deltas).\n  \n\n## Alternatives\n\n- Change notifications pattern with rich payloads – for use cases where API consumers would find calling back into Microsoft Graph onerous and absolute integrity guarantees are less critical.\n\n\n## Examples\n\n### Change tracking on entity set\n\n```xml\n<Function Name=\"delta\" IsBound=\"true\">\n        <Parameter Name=\"bindingParameter\" Type=\"Collection(graph.user)\" />\n        <ReturnType Type=\"Collection(graph.user)\" />\n</Function>\n<EntitySet Name=\"users\" EntityType=\"graph.user\"> \n    <Annotation Term=\"Org.OData.Capabilities.V1.ChangeTracking\"> \n      <Record> \n        <PropertyValue Property=\"Supported\" Bool=\"true\" /> \n      </Record> \n    </Annotation> \n</EntitySet> \n```\n\n### Change tracking on navigation property\n\n```xml\n<EntityType Name=\"educationRoot\">\n    <NavigationProperty Name=\"classes\" Type=\"Collection(graph.educationClass)\" ContainsTarget=\"true\" />\n    <NavigationProperty Name=\"me\" Type=\"graph.educationUser\" ContainsTarget=\"true\" />\n    <NavigationProperty Name=\"schools\" Type=\"Collection(graph.educationSchool)\" ContainsTarget=\"true\" />\n    <NavigationProperty Name=\"synchronizationProfiles\" Type=\"Collection(graph.educationSynchronizationProfile)\" ContainsTarget=\"true\"/>\n    <NavigationProperty Name=\"users\" Type=\"Collection(graph.educationUser)\" ContainsTarget=\"true\" />\n</EntityType>\n<Function Name=\"delta\" IsBound=\"true\">\n    <Parameter Name=\"bindingParameter\" Type=\"Collection(graph.educationClass)\" />\n    <ReturnType Type=\"Collection(graph.educationClass)\" />\n</Function>\n <Annotations Target=\"microsoft.graph.educationRoot/classes\">\n    <Annotation Term=\"Org.OData.Capabilities.V1.ChangeTracking\">\n      <Record>\n        <PropertyValue Property=\"Supported\" Bool=\"true\" />\n      </Record>\n    </Annotation>\n</Annotations>\n```\n### Change tracking on function that return an entity collection\n\nFirstly, an API designer needs to define the function as composable (so that a delta function can be added to it), by adding the `IsComposable` annotation:\n\n```xml\n<Function Name=\"getAllRecordings\" IsBound=\"true\" EntitySetPath=\"bindingParameter/recordings\" IsComposable=\"true\">\n  <Parameter Name=\"bindingParameter\" Type=\"Collection(self.onlineMeeting)\" />\n  <ReturnType Type=\"Collection(self.meetingRecording)\" />\n</Function>\n```\n\nNext, define the `delta` function. The binding parameter and the return type of the delta function MUST be the same as the return type of the target `getAllRecordings` function:\n\n```xml\n<Function Name=\"delta\" IsBound=\"true\" EntitySetPath=\"bindingParameter\">\n  <Parameter Name=\"bindingParameter\" Type=\"Collection(self.meetingRecording)\" />\n  <ReturnType Type=\"Collection(self.meetingRecording)\" />\n</Function>\n```\nFinally, for the function, the designer needs to add an annotation (either as a child of the entity or by targeting the entity type as below) stating that it supports change tracking (delta query):\n\n```xml\n<Annotations Target=\"self.getAllRecordings(Collection(self.onlineMeeting))\">\n  <Annotation Term=\"Org.OData.Capabilities.V1.ChangeTracking\">\n    <Record>\n      <PropertyValue Property=\"Supported\" Bool=\"true\" />\n    </Record>\n  </Annotation>\n</Annotations>\n```\nHere is the HTTP request to start the change tracking process on `getAllRecordings`\n\n```http\nGET https://graph.microsoft.com/v1.0/communications/onlineMeetings/getAllRecordings/delta\n```\n\n### Delta payload\n\n Here after the initial delta call, a user resource is updated, and there is one user added to and one removed from that user’s directReports collection. Additionally, a second user is deleted. In this case, there are no further pages of change records currently available. For detailed sequence of requests see [Change Tracking](https://learn.microsoft.com/en-us/graph/delta-query-overview?tabs=http#use-delta-query-to-track-changes-in-a-resource-collection).\n\n```http\nGET https://graph.microsoft.com/v1.0/users/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ\n\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#users\",\n    \"@odata.deltaLink\": \"https://graph.microsoft.com/v1.0/users/delta?$deltatoken=mS5DuRZGjVL-abreviated\",\n    \"value\": [\n        {\n            \"businessPhones\": [\"+1 309 555 0104\"],\n            \"displayName\": \"Grady Archie\", \n            \"givenName\": \"Grady\", \n            \"jobTitle\": \"Designer\", \n            \"mail\": \"GradyA@contoso.onmicrosoft.com\", \n            \"officeLocation\": \"19/2109\", \n            \"preferredLanguage\": \"en-US\", \n            \"surname\": \"Archie\", \n            \"userPrincipalName\": \"GradyA@contoso.onmicrosoft.com\", \n            \"id\": \"0baaae0f-b0b3-4645-867d-742d8fb669a2\", \n            \"directReports@delta\": [ \n                { \n                    \"@odata.type\": \"#microsoft.graph.user\", \n                    \"id\": \"99789584-a1e1-4232-90e5-866170e3d4e7\" \n                } ,\n                { \n                    \"id\": \"66789583-f1e2-6232-70e5-366170e3d4a6\",\n                    \"@removed\": {\n                        \"reason\": \"deleted\"\n                    }\n                }\n            ] \n        }, \n        { \n            \"id\": \"0bbbbb0f-b0b3-4645-867d-742d8fb669a2\", \n            \"@removed\": { \n                \"reason\": \"changed\" \n            } \n        } \n    ] \n}\n```\n"
  },
  {
    "path": "graph/patterns/default-properties.md",
    "content": "# Default properties\n\nMicrosoft Graph API Design Pattern\n\n*The default properties pattern allows API producers to omit specific properties from the response unless they are explicitly requested using `$select`.*\n\n## Problem\n\nAPI designers want to control the set of properties that their entities return by default, when the incoming request does not specify a `$select`. This can be desirable when an entity type has many properties or an API producer needs to add properties that are computationally expensive to return by default.\n\n## Solution\n\nFor incoming requests targeting an entity type where the caller does not specify a `$select` clause, API producers **may** return a subset of the entity type's properties, omitting computationally expensive properties. To get the non-default properties of an entity type, callers must explicitly request them using `$select`.\n\nThe pattern also uses an instance annotation to inform callers that other properties are also available. The same annotation is also used to encourage callers to use `$select`.\n\n## When to use this pattern\n\nAPI producers should use this pattern when adding expensive or non-performant properties to an existing entity type, or when adding properties to an entity type that has already grown too large (with more than 20 properties).\n\n## Issues and considerations\n\n- Do **not** rely on the `ags:Default` schema annotation for default properties functionality, as this is a legacy implementation. Returning default properties **must** be implemented by API producers.\n- Changing a default property to non-default is considered a breaking change.\n- One of the challenges with default properties is informing developers that the response does not contain the full set of properties. To solve for this discovery problem, if the response contains default properties only, then:\n  - the response **must** contain a `@microsoft.graph.tips` instance annotation.\n  - the `@microsoft.graph.tips` instance annotation **must** only be emitted if the client uses \"developer mode\" via the `Prefer: ms-graph-dev-mode` HTTP request header. It is expected that this header will only be used by client developer and scripting tools like Graph Explorer, the Microsoft Graph Postman collections, and Microsoft Graph PowerShell.\n  - the `@microsoft.graph.tips` instance annotation value **must** contain \"This request only returns a subset of the resource's properties. Your app will need to use $select to return non-default properties. To find out what other properties are available for this resource see https://learn.microsoft.com/graph/api/resources/{entityTypeName}\".\n- Callers must be able to use `$filter` with non-default properties, even though they won't show up by default in the response.\n\nAdditionally, for incoming requests targeting an entity type where the caller does not specify a `$select` clause, the API Gateway Service will inject a `@microsoft.graph.tips` instance annotation, informing callers to use $select, when in \"developer mode\".\nAPI producers who use [response passthrough](https://dev.azure.com/msazure/One/_wiki/wikis/Microsoft%20Graph%20Partners/391069/Enabling-response-passthrough) must also implement this behavior, supplying the same information as shown in the [examples section below](#calling-an-api-without-using-select).\n\n## Examples\n\nIn this example we'll use the following `channel` entity type.\n\n```xml\n<EntityType Name=\"channel\" BaseType=\"graph.entity\">\n  <Property Name=\"createdDateTime\" Type=\"Edm.DateTimeOffset\"/>\n  <Property Name=\"description\" Type=\"Edm.String\"/>\n  <Property Name=\"displayName\" Type=\"Edm.String\" Nullable=\"false\"/>\n  <Property Name=\"email\" Type=\"Edm.String\"/>\n  <Property Name=\"isFavoriteByDefault\" Type=\"Edm.Boolean\"/>\n  <Property Name=\"membershipType\" Type=\"graph.channelMembershipType\"/>\n  <!-- moderationSettings is a new computed property that is very expensive -->\n  <Property Name=\"moderationSettings\" Type=\"graph.channelModerationSettings\"/> \n  <Property Name=\"webUrl\" Type=\"Edm.String\"/>\n  <Property Name=\"filesFolderWebUrl\" Type=\"Edm.String\"/>\n</EntityType>\n```\n\nIn this scenario, the API producer wants to add the `moderationSettings` property to the `channel` entity type.\nBut when paging through 1000 channels at a time, this additional property will introduce a considerable increase in the response times.\nThe API producer will use the default properties pattern here, and **not** return `moderationSettings` by default.\n\n### Calling an API with default properties\n\nIn this example, the caller, using Graph Explorer, does not use $select, and the API returns just the default properties.\n\n#### Request\n\n```http\nGET /teams/{id}/channels\nPrefer: ms-graph-dev-mode\n```\n\n#### Response\n\n```http\n200 ok\nContent-type: application/json\n```\n\n```json\n{\n    \"@odata.context\": \"https://graph.microsoft.com/beta/$metadata#Collection(microsoft.graph.channel)\",\n    \"@microsoft.graph.tips\": \"This request only returns a subset of the resource properties. Your app will need to use $select to return non-default properties. To find out what other properties are supported for this resource, please see the Properties section in https://learn.microsoft.com/graph/api/resources/channel.\",\n    \"value\": [\n        {\n            \"displayName\": \"My First Shared Channel\",\n            \"description\": \"This is my first shared channels\",\n            \"id\": \"19:PZC_kAPAm12RPBMkEaJyXaY_d2PE6mJV6MzO1EiCbnk1@thread.tacv2\",\n            \"membershipType\": \"shared\",\n            \"email\": \"someemail@dot.com\",\n            \"webUrl\": \"webUrl-value\",\n            \"filesFolderWebUrl\": \"sharePointUrl-value\",\n            \"tenantId\": \"tenantId-value\",\n            \"isFavoriteByDefault\": null,\n            \"createdDateTime\": \"2019-08-07T19:00:00Z\"\n        },\n        {\n            \"displayName\": \"My Second Private Channel\",\n            \"description\": \"This is my second shared channels\",\n            \"id\": \"19:PZC_kAPAm12RPBMkEaJyXaY_d2PE6mJV6MzO1EiCbnk2@thread.tacv2\",\n            \"membershipType\": \"private\",\n            \"email\": \"someemail2@dot.com\",\n            \"webUrl\": \"webUrl-value2\",\n            \"filesFolderWebUrl\": \"sharePointUrl-value2\",\n            \"tenantId\": \"tenantId-value\",\n            \"isFavoriteByDefault\": null,\n            \"createdDateTime\": \"2019-08-09T19:00:00Z\"\n        }\n    ]\n}\n```\n\nIn the response, we can see that `moderationSettings` is not being returned. Additionally, the API producer is returning a `tips` instance annotation, informing the caller that this response only returns default properties, how to get the non-default properties, and where to find information about this type's properties. The `tips` instance annotation is only emitted if the `Prefer: ms-graph-dev-mode` HTTP request header is present.\n\n### Calling an API with default properties and $select\n\nIn this example, the caller needs `moderationSettings` for their API scenario.  They try this out in Graph Explorer first.\n\n#### Request\n\n```http\nGET /teams/{id}/channels?$select=id,membershipType,moderationSettings\nPrefer: ms-graph-dev-mode\n```\n\n#### Response\n\n```http\n200 ok\nContent-type: application/json\n```\n\n```json\n{\n    \"@odata.context\": \"https://graph.microsoft.com/beta/$metadata#Collection(microsoft.graph.channel)\",\n    \"value\": [\n        {\n            \"id\": \"19:PZC_kAPAm12RPBMkEaJyXaY_d2PE6mJV6MzO1EiCbnk1@thread.tacv2\",\n            \"membershipType\": \"shared\",\n            \"channelModerationSettings\": {\n                \"userNewMessageRestriction\": \"everyone\",\n                \"replyRestriction\": \"everyone\",\n                \"allowNewMessageFromBots\": true,\n                \"allowNewMessageFromConnectors\": true\n            }\n        },\n        {\n            \"id\": \"19:PZC_kAPAm12RPBMkEaJyXaY_d2PE6mJV6MzO1EiCbnk2@thread.tacv2\",\n            \"membershipType\": \"private\",\n            \"channelModerationSettings\": {\n                \"userNewMessageRestriction\": \"moderators\",\n                \"replyRestriction\": \"authorAndModerators\",\n                \"allowNewMessageFromBots\": true,\n                \"allowNewMessageFromConnectors\": true\n            }\n        }\n    ]\n}\n```\n\nIn this case, because the request has a `$select`, the `tips` instance annotation is not emitted.\n\n### Calling an API without using $select\n\nThe caller makes a `GET` request without $select, to an API that doesn't have any default properties, via Graph Explorer.\n\n#### Request\n\n```http\nGET /me/todo/lists\nPrefer: ms-graph-dev-mode\n```\n\n#### Response\n\n```http\n200 ok\nContent-type: application/json\n```\n\n```json\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#users('99a6e897-8c54-4354-a739-626fbe28ed78')/todo/lists\",\n    \"@microsoft.graph.tips\": \"Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET me/todo/lists?$select=displayName,isOwner\",\n    \"value\": [\n        {\n            \"@odata.etag\": \"W/\\\"c5yMNreru0OMO71/IwuKGQAG6WUnjQ==\\\"\",\n            \"displayName\": \"Tasks\",\n            \"isOwner\": true,\n            \"isShared\": false,\n            \"wellknownListName\": \"defaultList\",\n            \"id\": \"AAMkADU3NTBhNWUzLWE0MWItNGViYy1hMTA0LTkzNjRlYTA2ZWI2ZAAuAAAAAAAFup0i-hqtR5N14AJlh2qTAQATqGUvrHrTEbWPAKDJQ2mMAAACWIG1AAA=\"\n        },\n        {\n            \"@odata.etag\": \"W/\\\"c5yMNreru0OMO71/IwuKGQAG6WUnmQ==\\\"\",\n            \"displayName\": \"Outlook Commitments\",\n            \"isOwner\": true,\n            \"isShared\": false,\n            \"wellknownListName\": \"none\",\n            \"id\": \"AQMkADU3NTBhNWUzLWE0MWItNGViYy1hMTA0LTkzNjRlYTA2ZWI2ZAAuAAADBbqdIv4arUeTdeACZYdqkwEAc5yMNreru0OMO71-IwuKGQABWbOTpQAAAA==\"\n        }\n    ]\n}\n```\n\nNotice how for this scenario, where there are no default properties and the caller does not use `$select`, there's a `tips` instance annotation, encouraging the app developer to use `$select`. This `tips` annotation is automatically added to the response by the API gateway service, as long as the workload service doesn't use response passthrough (in which case it is the responsibility of the workload service).\n"
  },
  {
    "path": "graph/patterns/dictionary-client-guidance.md",
    "content": "# Dictionary types\n\n> **Note:** This document will be moved into a central client guidance document in the future.\n\n*The client guidance is a collection of additional information provided to SDK implementers and client applications. This information is meant to help understand how various guidelines and concepts translate in their world and clarify a few unknowns. Always read the corresponding guideline first to get a contextual understanding.*\n\nFor more information, see the [Dictionary](./dictionary.md) pattern.\n\n## OpenAPI example\n\nThe following json-schema/OpenAPI example defines a dictionary of which values are of type **RoleSettings**.\n\nIn **components** in **schemas**:\n\n```json\n{\n  \"roleSettings\": {\n    \"type\": \"object\",\n      \"properties\": {\n        \"domain\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n```\n\n```json\n{\n  \"type\": \"object\",\n  \"patternProperties\": {\n    \".*\": {\n      \"$ref\": \"#/components/schemas/roleSettings\"\n    },\n    \"additionalProperties\": false\n  }\n}\n```\n\n## SDK support\n\nSDKs need to provide support for dictionary types so that SDK consumers get a delightful development experience. Examples are provided for different languages. Other aspects need to be taken into consideration:\n\n- Dictionaries support OData annotations (values prefixed with **@OData**); such annotations should not be inserted directly in the dictionary but rather in the additional properties manager.\n- Dictionary types can inherit another dictionary type; this inheritance must be respected.\n- Dictionary values can be of union types; if the target language doesn't support union types, a wrapper type should be generated as a backward compatible solution with properties for each type of the union.\n\n### Dotnet\n\n```CSharp\nDictionary<string, RoleSettings>\n```\n\n### Java\n\n```Java\nMap<string, RoleSettings>\n```\n\n### JavaScript/TypeScript\n\n```TypeScript\nMap<string, RoleSettings>\n```\n\nor\n\n```JavaScript\n{\n  [key: string]: {value: RoleSettings}\n}\n```\n\n## Request builder generation annotation\n\nBy default, SDKs are not required to contain a set of request builders to run CRUD requests on entries in the dictionary. The dictionary is updated as a whole by consumers by sending requests to the parent entity.\n\nIf a **SupportedHttpMethod** annotation is specified for the dictionary type, request builders should be generated to allow consumers to automatically update the entries.\n"
  },
  {
    "path": "graph/patterns/dictionary.md",
    "content": "# Dictionary\n\nMicrosoft Graph API Design Pattern\n\n_The dictionary type provides the ability to create a set key/value pairs where the set of keys is dynamically specified by the API consumer._\n\n## Problem\n\nThe API design requires a resource to include an unknown quantity of data values whose keys are defined by the API consumer.\n\n## Solution\n\nAPI designers use a JSON object to represent a dictionary in an `application/json` response payload. When describing the model in CSDL, a new complex type can be created that derives from `graph.Dictionary` and optionally uses the `Org.OData.Validation.V1.OpenPropertyTypeConstraint` to constrain the type that can be used for the values in the dictionary as appropriate.\n\nDictionary entries can be added, removed, or modified via `PATCH` to the dictionary property. Entries are removed by setting the property to `null`.\n\n## When to use this pattern\n\nBefore using a dictionary type in your API definition, make sure that your scenario fits the following criteria:\n\n- The data values MUST be related to one another semantically as a collection.\n- The values MUST be primitive or complex types.\n- The client MUST define the keys of this type, as opposed to the service defining them in advance.\n\n### Alternatives\n\n- [Open extensions](https://docs.microsoft.com/graph/extensibility-open-users) when you want to provide clients the ability to extend Microsoft Graph.\n- [Complex types](https://docs.microsoft.com/odata/webapi/complextypewithnavigationproperty) when the set of data values are known.\n\n## Issues and considerations\n\nDictionaries, sometimes called maps, are a collection of name-value pairs. They allow dynamic data sets to be accessed in a systematic manner and are a good compromise between a strictly defined-ahead-of-time structure with all its named properties and a loosely defined dynamic object (such as OData OpenTypes).\n\nBecause dictionary entries are removed by setting the value to `null`, dictionaries don't support null values.\n\nFor more information, see the [OData reference](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#dictionary).\n\n## Examples\n\n### String dictionary\n\n#### CSDL declaration\nThe following example demonstrates defining a dictionary that can contain string values.\n\n```xml\n<Schema Namespace=\"microsoft.graph\"> <!--NOTE: the namespace that declares the Dictionary complex type *must* be microsoft.graph-->\n  <ComplexType Name=\"Dictionary\" OpenType=\"true\">\n    <Annotation Term=\"Core.Description\" String=\"A dictionary of name-value pairs. Names must be valid property names, values may be restricted to a list of types via an annotation with term `Validation.OpenPropertyTypeConstraint`.\" />\n  </ComplexType>\n</Schema>\n<Schema Namespace=\"WorkloadNamespace\">\n  <ComplexType Name=\"stringDictionary\" OpenType=\"true\" BaseType=\"microsoft.graph.Dictionary\">\n    <Annotation Term=\"Org.OData.Validation.V1.OpenPropertyTypeConstraint\">\n      <Collection>\n        <String>Edm.String</String>\n      </Collection>\n    </Annotation>\n  </ComplexType>\n</Schema>\n```\n\nPlease note that schema validation will fail due to the casing of `Dictionary`.\nThis warning should be suppressed.\n\n#### Defining a dictionary property\nThe following example shows defining a dictionary property, \"userTags\", on the item entity type.\n\n```xml\n<EntityType Name=\"item\">\n  ...\n  <Property Name=\"userTags\" Type=\"WorkloadNamespace.stringDictionary\"/>\n</EntityType>\n```\n\n#### Reading a dictionary\nDictionaries are represented in JSON payloads as a JSON object, where the property names are comprised of the keys and their values are the corresponding key values. \n\nThe following example shows reading an item with a dictionary property named \"userTags\":\n\n```HTTP\nGET /item\n```\nResponse:\n```json\n{\n  ...\n  \"userTags\":\n  {\n    \"anniversary\": \"2002-05-19\",\n    \"favoriteMovie\": \"Princess Bride\"\n  }\n}\n```\n\n#### Setting a dictionary value\nThe following example shows setting a dictionary value.  If \"hairColor\" already exists, it is updated, otherwise it is added.\n\n```http\nPATCH /item/userTags\n```\n```json\n{\n   \"hairColor\": \"purple\"\n}\n```\n\n#### Deleting a dictionary value\nA dictionary value can be removed by setting the value to null.\n```http\nPATCH /item/userTags\n```\n```json\n{\n   \"hairColor\": null\n}\n```\n\n### Complex typed dictionary\n\n#### CSDL declaration\nDictionaries can also contain complex types whose values may be constrained to a particular set of complex types.\n\nThe following example defines a complex type **roleSettings**, an **assignedRoleGroupDictionary** that contains **roleSettings**, and an **assignedRoles** property that uses the dictionary..\n\n```xml\n<Schema Namespace=\"microsoft.graph\"> <!--NOTE: the namespace that declares the Dictionary complex type *must* be microsoft.graph-->\n  <ComplexType Name=\"Dictionary\" OpenType=\"true\">\n    <Annotation Term=\"Core.Description\" String=\"A dictionary of name-value pairs. Names must be valid property names, values may be restricted to a list of types via an annotation with term `Validation.OpenPropertyTypeConstraint`.\" />\n  </ComplexType>\n</Schema>\n<Schema Namespace=\"WorkloadNamespace\">\n  <EntityType Name=\"principal\">\n    ...\n    <Property Name=\"assignedRoles\" Type=\"WorkloadNamespace.assignedRoleGroupDictionary\">\n  </EntityType>\n\n  <ComplexType Name=\"roleSettings\">\n    <Property Name =\"domain\" Type=\"Edm.String\" Nullable=\"false\" />\n  </ComplexType>\n\n  <ComplexType Name=\"assignedRoleGroupDictionary\" BaseType=\"microsoft.graph.Dictionary\">\n    <!-- Note: Strongly-typed dictionary of roleSettings keyed by name of roleGroup. -->\n    of roleSettings\n    keyed by name of roleGroup. -->\n    <Annotation Term=\"Org.OData.Validation.V1.OpenPropertyTypeConstraint\">\n      <Collection>\n        <String>microsoft.graph.roleSettings</String>\n      </Collection>\n    </Annotation>\n  </ComplexType>\n</Schema>\n```\n\n#### Reading a entity with a complex-typed dictionary\n\nThe following example illustrates reading an entity containing the complex-typed dictionary \"assignedRoles\".\n\n```HTTP\nGET /users/10\n```\n\nResponse:\n\n```json\n{\n  \"id\": \"10\",\n  \"displayName\": \"Jane Smith\",\n  \"assignedRoles\": {\n    \"author\": {\n      \"domain\": \"contoso\"\n    },\n    \"maintainer\": {\n      \"domain\": \"fabrikam\"\n    },\n    \"architect\": {\n      \"domain\": \"adventureWorks\"\n    }\n  }\n}\n```\n\n#### Reading the dictionary property\nThe following example shows getting just the \"assignedRoles\" dictionary property.\n\n```HTTP\nGET /users/10/assignedRoles\n```\n\nResponse:\n\n```json\n{\n  \"author\": {\n    \"domain\": \"contoso\"\n  },\n  \"maintainer\": {\n    \"domain\": \"fabrikam\"\n  },\n  \"architect\": {\n    \"domain\": \"adventureWorks\"\n  }\n}\n```\n\n#### Reading an individual entry from the dictionary\nThe following example shows reading a single complex-typed entry named \"author\" from the \"assignedRoles\" dictionary.\n\n```HTTP\nGET /users/10/assingedRoles/author\n```\n\nResponse:\n\n```json\n{\n  \"domain\": \"contoso\"\n}\n```\n\n#### Setting an individual entry in the dictionary\nThe following examples shows updating the dictionary to set the value for the \"author\" entry. If the \"author\" entry does not exists it is added with the specified values; otherwise, if the \"author\" entry already exists, it is updated with the specified values (unspecified values are left unchanged).\n\n```HTTP\nPATCH /users/10/assignedRoles/author\n```\n```json\n{\n  \"author\" : {\n     \"domain\": \"contoso\"\n  }\n}\n```\n\n#### Deleting an individual entry from the dictionary\nThe following example shows deleting the \"author\" entry by setting its value to null.\n\n```HTTP\nPATCH /users/10/assignedRoles\n```\n```json\n{\n  \"author\": null\n}\n```\n\n#### Setting multiple dictionary entries\nThe following example sets values for the \"author\", \"maintainer\" and \"viewer\" entries, and removes the \"architect\" entry by setting it to null.\n\n```HTTP\nPATCH /users/10/assignedRoles\n```\n```json\n{\n  \"author\": {\n    \"domain\": \"contoso1\"\n  },\n  \"maintainer\": {\n    \"domain\": \"fabrikam1\"\n  },\n  \"reviewer\": {\n    \"domain\": \"fabrikam\"\n  },\n  \"architect\": null\n}\n\n```\n\n## See also\n\n- [SDK implementation guidance](./dictionary-client-guidance.md)\n"
  },
  {
    "path": "graph/patterns/enums.md",
    "content": "### Enums\r\n\r\nIn OData, enums represent a subset of the nominal type they rely on, and are especially useful in cases where certain properties have predefined, limited options.\r\n\r\n```xml\r\n<EnumType Name=\"color\">\r\n    <Member Name=\"Red\" Value=\"0\" />\r\n    <Member Name=\"Green\" Value=\"1\" />\r\n    <Member Name=\"Blue\" Value=\"2\" />\r\n</EnumType>\r\n```\r\n\r\n#### Pros\r\n\r\n- Our SDK generators will translate the enum to the best representation of the target programming language, resulting in a better developer experience and free client side validation\r\n\r\n#### Cons\r\n\r\n- Adding a new value requires to go through a (generally fast) API Review\r\n- If the enum is not [evolvable](./patterns/evolvable-enums.md), adding a new value is a breaking change and will generally not be allowed\r\n\r\n#### Enum or Booleans\r\n\r\nEnumerations are a good alternative to Booleans when one of the two values (`true`, `false`) conveys other possible values not yet conceived. Let's assume we have an `publicNotification` type and a property to communicate how to display it:\r\n\r\n```xml\r\n<ComplexType Name=\"publicNotification\">\r\n  <Property Name=\"title\" Type=\"Edm.String\" />\r\n  <Property Name=\"message\" Type=\"Edm.String\" />\r\n  <Property Name=\"displayAsTip\" Type=\"Edm.Boolean\" />\r\n</ComplexType>\r\n```\r\n\r\nThe `false` value here merely communicates that the notification shall not be displayed as a tip. What if, in the future, the notification could be displayed as a `tip` or `alert`, and then in a more distant future, a `dialog` option is viable?\r\n\r\nWith the current model, the only way is to add more boolean properties to convey the new information:\r\n\r\n```diff\r\n<ComplexType Name=\"publicNotification\">\r\n  <Property Name=\"title\" Type=\"Edm.String\" />\r\n  <Property Name=\"message\" Type=\"Edm.String\" />\r\n  <Property Name=\"displayAsTip\" Type=\"Edm.Boolean\" />\r\n+ <Property Name=\"displayAsAlert\" Type=\"Edm.Boolean\" />\r\n+ <Property Name=\"displayAsDialog\" Type=\"Edm.Boolean\" />\r\n</ComplexType>\r\n```\r\n\r\nAdditionally speaking, the workload will now also have to validate the data structure and make sure that only one of the 3 values is `true`\r\n\r\nBy using an evolvable enum, instead, all we need to do is to add new members:\r\n\r\n```diff\r\n<ComplexType Name=\"publicNotification\">\r\n  <Property Name=\"title\" Type=\"Edm.String\" />\r\n  <Property Name=\"message\" Type=\"Edm.String\" />\r\n+ <Property Name=\"displayMethod\" Type=\"microsoft.graph.displayMethod\" />\r\n-  <Property Name=\"displayAsTip\" Type=\"Edm.Boolean\" />\r\n- <Property Name=\"displayAsAlert\" Type=\"Edm.Boolean\" />\r\n- <Property Name=\"displayAsDialog\" Type=\"Edm.Boolean\" />\r\n</ComplexType>\r\n```\r\n\r\n```xml\r\n<EnumType Name=\"displayMethod\">\r\n    <Member Name=\"tip\" Value=\"0\" />\r\n    <Member Name=\"unknownFutureValue\" Value=\"1\" />\r\n    <Member Name=\"alert\" Value=\"2\" />\r\n    <Member Name=\"dialog\" Value=\"3\" />\r\n</EnumType>\r\n```\r\n\r\nSimilarly speaking, if you find yourself using a `nullable` Enum, that is a indication that maybe what you are trying to model is something that has 3 states and an enum is more appropraite. For instance, let's assume we have a boolean property called `syncEnabled`, where `null` means that the value is undefined and inherited from the general tenant configuration. Instead of modelling like a boolean:\r\n\r\n```xml\r\n<Property Name=\"syncEnabled\" Type=\"Edm.Boolean\" Nullable=\"true\"/>\r\n```\r\n\r\nAn enum not only better conveys the message:\r\n\r\n```xml\r\n<EnumType Name=\"syncState\">\r\n    <Member Name=\"enabled\" Value=\"0\" />\r\n    <Member Name=\"disabled\" Value=\"1\" />\r\n    <Member Name=\"tenantInherit\" Value=\"2\" />\r\n    <Member Name=\"unknownFutureValue\" Value=\"3\" />\r\n</EnumType>\r\n```\r\n\r\nbut it is also open for future scenarios:\r\n\r\n```diff\r\n<EnumType Name=\"syncState\">\r\n    <Member Name=\"enabled\" Value=\"0\" />\r\n    <Member Name=\"disabled\" Value=\"1\" />\r\n    <Member Name=\"tenantInherit\" Value=\"2\" />\r\n    <Member Name=\"unknownFutureValue\" Value=\"3\" />\r\n+   <Member Name=\"groupInherit\" Value=\"4\" />\r\n</EnumType>\r\n```\r\n\r\nAdditionally speaking, depending on the situation, a nullable enum can very likely be avoided by adding a `none` member.\r\n\r\nIf used, `EnumType` names should be singular if the are non-flags enums, and the names should be plural if they are flags enums.\r\n\r\n#### Flag Enums or Collection of Enums\r\n\r\nIn case an enum can have multiple values at the same time the tentation is to model the property as a collection of Enums:\r\n\r\n```xml\r\n<Property Name=\"displayMethods\" Type=\"Collection(displayMethod)\"/>\r\n```\r\n\r\nHowever, [Flagged Enums](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530378) can model this use case scenario:\r\n\r\n```diff\r\n- <EnumType Name=\"displayMethod\">\r\n+ <EnumType Name=\"displayMethod\" isFlag=\"true\">\r\n-     <Member Name=\"tip\" Value=\"0\" />\r\n+     <Member Name=\"tip\" Value=\"1\" />\r\n-     <Member Name=\"unknownFutureValue\" Value=\"1\" />\r\n+     <Member Name=\"unknownFutureValue\" Value=\"2\" />\r\n-     <Member Name=\"alert\" Value=\"2\" />\r\n+     <Member Name=\"alert\" Value=\"4\" />\r\n-    <Member Name=\"dialog\" Value=\"3\" />\r\n+    <Member Name=\"dialog\" Value=\"8\" />\r\n</EnumType>\r\n```\r\n\r\nWith such enum, customers can select multiple values in a single field:\r\n\r\n`displayMethod = tip | alert`\r\n\r\nIn cases where two properties want to use the same *conceptual* `EnumType`, but one property is a collection while the other is single-values, the model should define *two* separate `EnumType`s, one being a non-flags enum with a singular name and the other marked as a flags enum with its name being the plural form of the non-flags enum.\r\n\r\n#### Flag enum + non-flag enum\r\n\r\nThere are occasions where one API will want to use a non-flag enum, but another API will want a flags enum. \r\nFor example, the `displayMethod` example above may have one API that is configuring which display methods to use, and another API which is configuring that particular display method. \r\nIn this case, the first API will want a flags enum, but the second API will want to only allow configuring one display method at a time, and will therefore prefer a non-flags enum.\r\n\r\nTwo enum types should be defined, one as a flags enum and the other as a non-flags enum.\r\nThe flags enum should be named such that it is plural, and the non-flags enum should be named such that it is singular.\r\nThe two types should be kept in sync with each other.\r\n"
  },
  {
    "path": "graph/patterns/evolvable-enums.md",
    "content": "# Evolvable enums\n\nMicrosoft Graph API Design Pattern\n\n*The evolvable enums pattern allows API producers to extend enumerated types with new members without breaking API consumers.*\n\nNote: You might be interested in reading the [Enum guidance](./enums.md) first\n\n## Problem\n\nFrequently API producers want to add new members to an enum type after it is initially published. Some serialization libraries might fail when they encounter members in an enum type that were added after the serialization model was generated. In this documentation, we refer to any added enum members as unknown.\n\n## Solution\n\nThe solution is to add a 'sentinel' member named `unknownFutureValue` at the end of the currently known enum members. The API producer then replaces any member that is numerically after `unknownFutureValue` with `unknownFutureValue`.\n\nIf an API consumer can handle unknown enum values, the consumer can opt into receiving the unknown enum members by specifying the `Prefer: include-unknown-enum-members` HTTP header in their requests. The API producer then indicates that this preference has been applied by returning the `Preference-Applied: include-unknown-enum-members` HTTP header in the response.\n\n## When to use this pattern\n\nIt is a best practice to include an `unknownFutureValue` value when the enum is initially introduced to allow flexibility to extend the enum during the lifetime of the API. Even if the API producer believes that  they have included all possible members in an enum, we still strongly recommend that you include an `unknownFutureValue` member to allow for unforeseen future circumstances that may require extending the enum.\n\nThis pattern must not be used in scenarios where an API consumer wants to use enum members that are not known to the API producer.\n\n## Issues and considerations\n\nConsider the following:\n\n- An enum member with the name of `unknownFutureValue` MUST only be used as a sentinel value. An API producer MUST not include a member named `unknownFutureValue` in an enum for any other purpose.\n\n- Changing the value (that is, position) of the `unknownFutureValue` sentinel member is considered a breaking change and must follow the [deprecation](../deprecation.md) process.\n\n- Enum types can have multiple members with the same numeric value to allow for aliasing enum members. `unknownFutureValue` MUST not be aliased to any other enum member.\n\n- There is no ability for a client to indicate that it can handle a subset of unknown enum members. Instead, they can only specify that either they cannot handle any unknown enum members or they can handle any unknown enum members.\n\n- The `Prefer: include-unknown-enum-members` header applies to all included enums in the request/response. There is no way for an API consumer to apply the behavior to only a subset of enum types.\n\n- New values MUST not be inserted into the enum before `unknownFutureValue`. Implementers are recommended to make the numeric value of `unknownFutureValue` one greater than the last known enum member to ensure that there are no gaps into which a new member could be inadvertently added. The exception to this is the case of flagged enums, in which case the value of `unknownFutureValue` should be the next power of 2 value.\n\n- For flagged enums, care should be exercised to ensure that `unknownFutureValue` is not included in any enum members that represent a combination of other enum members.\n\n- If the value of a property containing a flag enum contains multiple unknown values, they should all be replaced with a single `unknownFutureValue` value (that is, there should not be multiple `unknownFutureValue` values returned).\n\n- If an API consumer specifies `unknownFutureValue` for the value of a property in a `POST`/`PUT` request or as a parameter of an action or function, the API producer must reject the request with a `400 Bad Request` HTTP status.\n\n- If an API consumer specifies `unknownFutureValue` for the value of a property in a `PATCH` request, the API producer must treat the property as if it were absent (that is, the existing value should not be changed). In the case where the API producer treats `PATCH` as an upsert, the call MUST be rejected with a `400 Bad Request` HTTP status.\n\n- If an API consumer specifies an enum member greater than `unknownFutureValue` in any request without specifying the `Prefer: include-unknown-enum-members` header, the API producer must reject the request with a `400 Bad Request` HTTP status.\n\n- For details about how the `unknownFutureValue` value is handled as part of a `$filter` clause, consult the following examples:\n\n  - **CSDL**\n    \n    ```xml\n        <EntityType Name=\"example\">\n            <Property Name=\"enumProperty\" Type=\"exampleEnum\"/>\n        </EntityType>\n        \n        <EnumType Name=\"exampleEnum\">\n            <Member Name=\"default\" Value=\"0\"/>\n            <Member Name=\"one\" Value=\"1\"/>\n            <Member Name=\"unknownFutureValue\" Value=\"2\"/>\n            <Member Name=\"newValue\" Value=\"3\"/>\n        </EnumType>\n    ```\n    \n  - **Filter behavior**\n    \n    | `$filter` clause | `Prefer: include-unknown-enum-members` Absent | `Prefer: include-unknown-enum-members` Present |\n    |---|---|---|\n    | `enumProperty eq unknownFutureValue`| Return entities where enumProperty has any value greater than `unknownFutureValue` replacing actual value with `unknownFutureValue`| Return nothing |\n    | `enumProperty gt unknownFutureValue`| Return entities where enumProperty has any value greater than `unknownFutureValue` replacing actual value with `unknownFutureValue` | Return entities where enumProperty has any value greater than `unknownFutureValue` |\n    | `enumProperty lt unknownFutureValue`| Return entities where enumProperty has any known value (i.e. less than `unknownFutureValue`) | Return entities where enumProperty has any value less than `unknownFutureValue`|\n    | `enumProperty eq newValue` | `400 Bad Request` | Return entities where enumProperty has the value `newValue` |\n    | `enumProperty gt newValue` | `400 Bad Request` | Return entities where enumProperty has a value greater than `newValue` |\n    | `enumProperty lt newValue` | `400 Bad Request` | Return entities where enumProperty has a value less than `newValue` |\n\n- If an evolvable enum is included in an `$orderby` clause, the actual numeric value of the member should be used to order the collection. After sorting, the member should then be replaced with `unknownFutureValue` when the `Prefer: include-unknown-enum-members` header is absent.\n\n## Examples\n\nFor the following examples, we consider the `managedDevice` entity, which refers to the `managedDeviceArchitecture` enum type.\n\n```xml\n<!-- Simplified entity for example purposes -->\n<EntityType Name=\"managedDevice\" BaseType=\"graph.entity\">\n    <Property Name=\"displayName\" Type=\"Edm.String\" />\n    <Property Name=\"processorArchitecture\" Type=\"graph.managedDeviceArchitecture\"/>\n</EntityType>\n```\n\nWhen the `managedDeviceArchitecture` enum was initially published to Microsoft Graph, it was defined as follows:\n\n```xml\n<!-- Slightly modified enum for example purposes -->\n<EnumType Name=\"managedDeviceArchitecture\">\n    <Member Name=\"unknown\" Value=\"0\"/>\n    <Member Name=\"x86\" Value=\"1\"/>\n    <Member Name=\"x64\" Value=\"2\"/>\n    <Member Name=\"arm\" Value=\"3\"/>\n    <Member Name=\"arm64\" Value=\"4\"/>\n    <Member Name=\"unknownFutureValue\" Value=\"5\"/>\n</EnumType>\n```\n\nThe enum was later extended to add a new value of `quantum`, leading to the following CSDL:\n\n```xml\n<EnumType Name=\"managedDeviceArchitecture\">\n    <Member Name=\"unknown\" Value=\"0\"/>\n    <Member Name=\"x86\" Value=\"1\"/>\n    <Member Name=\"x64\" Value=\"2\"/>\n    <Member Name=\"arm\" Value=\"3\"/>\n    <Member Name=\"arm64\" Value=\"4\"/>\n    <Member Name=\"unknownFutureValue\" Value=\"5\"/>\n    <Member Name=\"quantum\" Value=\"6\"/>\n</EnumType>\n```\n\n### Default behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture\n```\n\n```json\n{\n    \"value\": [\n        { \n            \"id\": \"0\", \n            \"displayName\": \"Surface Pro X\", \n            \"processorArchitecture\" : \"arm64\"\n        },\n        { \n            \"id\": \"1\",\n            \"displayName\": \"Prototype\",\n            \"processorArchitecture\": \"unknownFutureValue\"\n        }\n        { \n            \"id\": \"2\",\n            \"displayName\": \"My Laptop\", \n            \"processorArchitecture\": \"x64\"\n        }\n    ]\n}\n```\n\nIn this case, the value of the `processorArchitecture` property is `quantum`. However, because the client did not request the `include-unknown-enum-members` header, the value was replaced with `unknownFutureValue`.\n\n### Include opt-in header\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"value\": [\n        { \n            \"displayName\": \"Surface Pro X\", \n            \"processorArchitecture\" : \"arm64\"\n        },\n        { \n            \"displayName\": \"Prototype\",\n            \"processorArchitecture\": \"quantum\"\n        },\n        { \n            \"displayName\": \"My Laptop\",\n            \"processorArchitecture\": \"x64\"\n        }\n    ]\n}\n```\n\n### Default sort behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture&$orderBy=processorArchitecture\n```\n\n```json\n{\n    \"value\": [\n        { \n            \"displayName\": \"Surface Pro X\", \n            \"processorArchitecture\" : \"arm64\"\n        },\n        { \n            \"displayName\": \"My Laptop\", \n            \"processorArchitecture\": \"x64\"\n        },\n        { \n            \"displayName\": \"Prototype\",\n            \"processorArchitecture\": \"unknownFutureValue\"\n        }\n    ]\n}\n```\n\n### Sort behavior with opt-in header\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"value\": [\n        { \n            \"displayName\": \"Surface Pro X\",\n            \"processorArchitecture\" : \"arm64\"\n        },\n        { \n            \"displayName\": \"My Laptop\",\n            \"processorArchitecture\": \"x64\"\n        },\n        { \n            \"displayName\": \"Prototype\", \n            \"processorArchitecture\": \"quantum\"\n        }\n    ]\n}\n```\n\n### Default filter behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture&$filter=processorArchitecture gt x64\n```\n\n```json\n{\n    \"value\": [\n        { \n            \"displayName\": \"My Laptop\", \n            \"processorArchitecture\": \"x64\"\n        },\n        { \n            \"displayName\": \"Prototype\",\n            \"processorArchitecture\": \"unknownFutureValue\"\n        }\n    ]\n}\n```\n\n### Filter behavior with opt-in header\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?$select=displayName,processorArchitecture&$filter=processorArchitecture gt x64\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"value\": [\n        { \n            \"displayName\": \"My Laptop\", \n            \"processorArchitecture\": \"x64\"\n        },\n        { \n            \"displayName\": \"Prototype\", \n            \"processorArchitecture\": \"quantum\"\n        }\n    ]\n}\n```\n\n### Patch example\n\n```http\nPATCH https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/1\n\n{ \n    \"displayName\": \"Secret Prototype\",\n    \"processorArchitecture\": \"unknownFutureValue\"\n}\n```\n\n```json\n{\n    \"id\": \"1\",\n    \"displayName\": \"Secret Prototype\",\n    \"processorArchitecture\": \"unknownFutureValue\"\n}\n```\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/1\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"id\": \"1\",\n    \"displayName\": \"Secret Prototype\",\n    \"processorArchitecture\": \"quantum\"\n}\n```\n\n## Flag enum examples\n\nFor the following examples, we consider the `windowsUniversalAppX` entity, which refers to the `windowsArchitecture` flag enum type.\n\n```xml\n<!-- Simplified entity for example purposes -->\n<EntityType Name=\"windowsUniversalAppX\" BaseType=\"graph.entity\">\n    <Property Name=\"displayName\" Type=\"Edm.String\" />\n    <Property Name=\"applicableArchitectures\" Type=\"graph.windowsArchitecture\"/>\n</EntityType>\n```\n\nWhen the `windowsArchitecture` enum was initially published to Microsoft Graph, it was defined as follows:\n\n```xml\n<!-- Slightly modified enum for example purposes -->\n<EnumType Name=\"windowsArchitecture\" IsFlags=\"true\">\n    <Member Name=\"none\" Value=\"0\"/>\n    <Member Name=\"x86\" Value=\"1\"/>\n    <Member Name=\"x64\" Value=\"2\"/>\n    <Member Name=\"arm\" Value=\"4\"/>\n    <Member Name=\"neutral\" Value=\"8\"/>\n    <Member Name=\"unknownFutureValue\" Value=\"16\" />\n</EnumType>\n```\n\nThe enum was later extended to add a new value of `quantum`, leading to the following CSDL:\n\n```xml\n<EnumType Name=\"windowsArchitecture\" IsFlags=\"true\">\n    <Member Name=\"none\" Value=\"0\"/>\n    <Member Name=\"x86\" Value=\"1\"/>\n    <Member Name=\"x64\" Value=\"2\"/>\n    <Member Name=\"arm\" Value=\"4\"/>\n    <Member Name=\"neutral\" Value=\"8\"/>\n    <Member Name=\"unknownFutureValue\" Value=\"16\" />\n    <Member Name=\"quantum\" Value=\"32\" />\n</EnumType>\n```\n\n### Flag enum default behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?$select=displayName,applicableArchitectures\n```\n\n```json\n{\n    \"value\": [\n        { \n            \"id\": \"0\", \n            \"displayName\": \"OneNote\", \n            \"applicableArchitectures\" : \"neutral\"\n        },\n        { \n            \"id\": \"1\",\n            \"displayName\": \"Minecraft\",\n            \"applicableArchitectures\": \"x86,x64,arm,unknownFutureValue\"\n        }\n        { \n            \"id\": \"2\",\n            \"displayName\": \"Edge\", \n            \"applicableArchitectures\": \"x64,arm,unknownFutureValue\"\n        }\n    ]\n}\n```\n\nIn this case, the value of the `applicableArchitectures` property includes `quantum`. However, because the client did not request the `include-unknown-enum-members` header, the value was replaced with `unknownFutureValue`.\n\n### Flag enum include opt-in header\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?$select=displayName,applicableArchitectures\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"value\": [\n        { \n            \"id\": \"0\", \n            \"displayName\": \"OneNote\", \n            \"applicableArchitectures\" : \"neutral\"\n        },\n        { \n            \"id\": \"1\",\n            \"displayName\": \"Minecraft\",\n            \"applicableArchitectures\": \"x86,x64,arm,quantum\"\n        }\n        { \n            \"id\": \"2\",\n            \"displayName\": \"Edge\", \n            \"applicableArchitectures\": \"x64,arm,quantum\"\n        }\n    ]\n}\n```\n\n### Flag enum default filter behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?$select=displayName,applicableArchitectures&$filter=applicableArchitectures has unknownFutureValue\n```\n\n```json\n{\n    \"value\": [\n        { \n            \"id\": \"1\",\n            \"displayName\": \"Minecraft\",\n            \"applicableArchitectures\": \"x86,x64,arm,unknownFutureValue\"\n        }\n        { \n            \"id\": \"2\",\n            \"displayName\": \"Edge\", \n            \"applicableArchitectures\": \"x64,arm,unknownFutureValue\"\n        }\n    ]\n}\n```\n\n### Flag enum include opt-in header filter behavior\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?$select=displayName,applicableArchitectures&$filter=applicableArchitectures has unknownFutureValue\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"value\": []\n}\n```\n\n### Flag enum patch example\n\n```http\nPATCH https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/1\n\n{ \n    \"displayName\": \"Minecraft 2\",\n    \"processorArchitecture\": \"unknownFutureValue\"\n}\n```\n\n```json\n{\n    \"id\": \"1\",\n    \"displayName\": \"Minecraft 2\",\n    \"applicableArchitectures\": \"unknownFutureValue\"\n}\n```\n\n```http\nGET https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/1\n\nPrefer: include-unknown-enum-members\n```\n\n```json\nPreference-Applied: include-unknown-enum-members\n\n{\n    \"id\": \"1\",\n    \"displayName\": \"Minecraft 2\",\n    \"applicableArchitectures\": \"x86,x64,arm,quantum\"\n}\n```\n"
  },
  {
    "path": "graph/patterns/facets.md",
    "content": "# Facets\n\nMicrosoft Graph API Design Pattern\n\n*A frequent pattern in Microsoft Graph is to model multiple variants of a common concept as a single entity type with common properties and facets for variants.*\n\n## Problem\n\nAn API designer needs to model a set of heterogeneous resources that have common properties and behaviors and might express features of multiple variants at a time because variants are not mutually exclusive.\nFor example, a movie clip stored on OneDrive is both a file and a video. There are properties associated to each variant.\n\n## Solution\n\nAPI designers create multiple complex types to bundle properties for each variant, and then define an entity type with a property for each complex type to hold the properties of the variant.\n\nIn this solution, a child variant is identified by the presence of one or more facets in the parent object.\n\n## When to use this pattern\n\nThe facets pattern is useful when there is a number of variants and they are not mutually exclusive. It also makes it syntactically easier to query resources by using the OData `$filter` expression because it doesn't require casting.\n\nYou can consider related patterns such as [type hierarchy](./subtypes.md) and [flat bag of properties](./flat-bag.md).\n\n## Issues and considerations\n\nWhen introducing a new facet, you need to ensure that the new facet doesn't change the semantic of the model with its implicit constraints.\n\n## Example\n\nThe driveItem resource represents a file, folder, image, or other item stored in a drive and is modeled by using an entity type with multiple facets.\n\n```XML\n \n <EntityType Name=\"driveItem\" BaseType=\"graph.baseItem\" OpenType=\"true\" ags:MasterService=\"Microsoft.FileServices\" ags:WorkloadIds=\"Microsoft.Excel,Microsoft.Powerpoint,Microsoft.Teams.GraphSvc,Microsoft.Word\">\n        <Property Name=\"audio\" Type=\"graph.audio\" />\n        <Property Name=\"bundle\" Type=\"graph.bundle\" />\n        <Property Name=\"content\" Type=\"Edm.Stream\" />\n        <Property Name=\"cTag\" Type=\"Edm.String\" />\n        <Property Name=\"deleted\" Type=\"graph.deleted\" />\n        <Property Name=\"file\" Type=\"graph.file\" />\n        <Property Name=\"fileSystemInfo\" Type=\"graph.fileSystemInfo\" />\n        <Property Name=\"folder\" Type=\"graph.folder\" />\n        <Property Name=\"image\" Type=\"graph.image\" />\n        <Property Name=\"location\" Type=\"graph.geoCoordinates\" />\n        <Property Name=\"malware\" Type=\"graph.malware\" />\n        <Property Name=\"media\" Type=\"graph.media\" />\n        <Property Name=\"package\" Type=\"graph.package\" />\n        <Property Name=\"pendingOperations\" Type=\"graph.pendingOperations\" />\n        <Property Name=\"photo\" Type=\"graph.photo\" />\n        <Property Name=\"publication\" Type=\"graph.publicationFacet\" />\n        <Property Name=\"remoteItem\" Type=\"graph.remoteItem\" />\n        <Property Name=\"root\" Type=\"graph.root\" />\n        <Property Name=\"searchResult\" Type=\"graph.searchResult\" />\n        <Property Name=\"shared\" Type=\"graph.shared\" />\n        <Property Name=\"sharepointIds\" Type=\"graph.sharepointIds\" />\n        <Property Name=\"size\" Type=\"Edm.Int64\" />\n        <Property Name=\"source\" Type=\"graph.driveItemSource\" />\n        <Property Name=\"specialFolder\" Type=\"graph.specialFolder\" />\n        <Property Name=\"video\" Type=\"graph.video\" />\n        <Property Name=\"webDavUrl\" Type=\"Edm.String\" />\n     ...\n      </EntityType>\n```\n\nAn API request to get all items from a personal OneDrive returns a heterogenous collection with different facets populated. In the following example, there is a folder, a file, and an image in the collection. The image entity has two facets populated: file and image.\n\n```\nGET https://graph.microsoft.com/v1.0/me/drive/root/children\n\nResponse shortened for readability:\n \n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#users('93816c1c-1b19-41de-a322-a1643d7f4d39')/drive/root/children\",\n    \"value\": [\n        {\n            \"createdDateTime\": \"2021-07-07T13:59:47Z\",\n            \"name\": \"Microsoft Teams Chat Files\",\n             ...,\n            \"folder\": {\n                \"childCount\": 15\n            }\n        },\n        ...\n       {\n            \"createdDateTime\": \"2021-12-15T00:07:36Z\",\n            \"name\": \"Versioning and Deprecation.docx\",          \n            ...,           \n            \"file\": {\n                \"mimeType\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n                \"hashes\": {\n                    \"quickXorHash\": \"r2d9uZilW0zEIXwycymsUQzhV+U=\"\n                }\n            },\n           ...\n        },\n        {\n            \"createdDateTime\": \"2021-12-21T16:32:51Z\",\n            \"name\": \"WhaleShark.jpg\",\n            ...\n            \"file\": {\n                \"mimeType\": \"image/jpeg\",\n                \"hashes\": {\n                    \"quickXorHash\": \"2vHpAA7RDZJteIwl1pXR980xuh4=\"\n                }\n            },\n           ...,\n            \"image\": {}\n        }\n    ]\n```\n"
  },
  {
    "path": "graph/patterns/flat-bag.md",
    "content": "# Flat bag of properties\n\nMicrosoft Graph API Design Pattern\n\n*A known pattern in Microsoft Graph is to model multiple variants of a common concept as a single entity type with all potential properties plus an additional property to distinguish the variants.*\n\n## Problem\n\nAPI designers need to model a small and limited number of variants of a common concept with a concise list of non-overlapping properties and consistent behavior across variants. The designer also wants to simplify query construction.\n\n## Solution\n\nThe API designer creates one entity type with all the potential properties plus an additional property to distinguish the variants, often called `variantType`. For each value of `variantType`, some properties are meaningful and others are ignored.\n\n## When to use this pattern\n\nThe flat bag pattern is useful when there is a small number of variants with similar behavior, and variants are queried for mostly read-only operations. The pattern also makes it syntactically easier to query resources by using the OData `$filter` expression because it doesn't require casting.\n\n## Issues and considerations\n\nIn general, the flat bag pattern is the least recommended modeling choice because it is weakly typed, and it is difficult to semantically verify targeted resource modifications. However, there are circumstances when query simplicity and a limited number of properties might overweight considerations of a more strongly typed approach.\nThe pattern is not recommended for a large number of variants and properties because the payload becomes sparsely populated.\n\nYou can consider related patterns such as [type hierarchy](./subtypes.md) and [facets](./facets.md).\n\n## Example\n\nA good example for flat bag implementation is the recurrencePattern type on [recurrencePattern](https://docs.microsoft.com/graph/api/resources/recurrencepattern).\n\nThe recurrencePattern has six variants expressed as six different values of the `type` property (for example: daily, weekly, ...). The key here is that for each of these values, some properties are meaningful and others are ignored (for example: `daysOfWeek` is relevant when `type` is `weekly` but not when it is `daily`).\n\n```\n<EnumType Name=\"recurrencePatternType\">\n        <Member Name=\"daily\" Value=\"0\" />\n        <Member Name=\"weekly\" Value=\"1\" />\n        <Member Name=\"absoluteMonthly\" Value=\"2\" />\n        <Member Name=\"relativeMonthly\" Value=\"3\" />\n        <Member Name=\"absoluteYearly\" Value=\"4\" />\n        <Member Name=\"relativeYearly\" Value=\"5\" />\n</EnumType>\n\n<ComplexType Name=\"recurrencePattern\" ags:WorkloadIds=\"Microsoft.Exchange,Microsoft.IdentityGovernance.AccessReviews,Microsoft.IGAELM,Microsoft.PIM.AzureRBAC,Microsoft.Tasks,Microsoft.Teams.Shifts,Microsoft.Todo\" ags:PassthroughWorkloadIds=\"Microsoft.Exchange\">\n        <Property Name=\"dayOfMonth\" Type=\"Edm.Int32\" Nullable=\"false\" />\n        <Property Name=\"daysOfWeek\" Type=\"Collection(graph.dayOfWeek)\" />\n        <Property Name=\"firstDayOfWeek\" Type=\"graph.dayOfWeek\" />\n        <Property Name=\"index\" Type=\"graph.weekIndex\" />\n        <Property Name=\"interval\" Type=\"Edm.Int32\" Nullable=\"false\" />\n        <Property Name=\"month\" Type=\"Edm.Int32\" Nullable=\"false\" />\n        <Property Name=\"type\" Type=\"graph.recurrencePatternType\" />\n</ComplexType>\n```"
  },
  {
    "path": "graph/patterns/long-running-operations.md",
    "content": "# Long running operations\n\nMicrosoft Graph API Design Pattern\n\n*The long running operations (LRO) pattern provides the ability to model operations where processing a client request takes a long time, but the client isn't blocked and can do some other work until operation completion.*\n\n## Problem\n\nThe API design requires modeling operations on resources, which takes a long time\nto complete, so that API clients don't need to wait and can continue doing other\nwork while waiting for the final operation results. The client should be able to\nmonitor the progress of the operation and have an ability to cancel it if\nneeded.\n\nThe API needs to provide a mechanism to track the work\nbeing done in the background. The mechanism needs to be expressed in the same\nweb style as other interactive APIs. It also needs to support checking on the status and/or\nbeing notified asynchronously of the results.\n\n## Solution\n\nThe solution is to model the API as a synchronous service that returns a\nresource that represents the eventual completion or failure of a long running\noperation.\n\nThere are two flavors of this solution:\n\n- The returned resource is the targeted resource and includes the status of\n  the operation. This pattern is often called RELO (resource-based long running operation).\n\n<!-- markdownlint-disable MD033 -->\n<p align=\"center\">\n  <img src=\"RELO.gif\" alt=\"The status monitor LRO flow\"/>\n</p>\n<!-- markdownlint-enable MD033 -->\n\n- The returned resource is a new API resource called *stepwise operation* and is created to track the status. This LRO solution is similar to the concept of Promises or Futures in other programming languages.\n\n<!-- markdownlint-disable MD033 -->\n<p align=\"center\">\n  <img src=\"LRO.gif\" alt=\"The status monitor LRO flow\"/>\n</p>\n<!-- markdownlint-enable MD033 -->\n\nThe RELO pattern is the preferred pattern for long running operations and should be\nused wherever possible. The pattern avoids complexity, and consistent resource\npresentation makes things simpler for our users and tooling chain.\n\n- For the RELO pattern, you should return the Location header that indicates the location of the resource.\n  - The API response says the targeted resource is being created by returning a 201 status code and the resource URI is provided in the Location header, but the response indicates that the request is not completed by including \"Provisioning\" status.\n\n- For the LRO pattern, you should return the Location header that indicates the location of a new stepwise operation resource.\n  - The API response says the operation resource is being created at the URL provided in the Location header and indicates that the request is not completed by including a 202 status code.\n  - Microsoft Graph doesn’t allow tenant-wide operation resources; therefore, stepwise operations are often modeled as a navigation property on the target resource.\n\n- For most implementations of the LRO pattern (like the example above), there will be 3 permissions necessary to comply with the principle of least privilege: `ArchiveOperation.ReadWrite.All` to create the `archiveOperation` entity, `ArchiveOperation.Read.All` to track the `archiveOperation` entity to completion, and `Archives.Read.All` to retrieve the `archive` that was created as a result of the operation.\nFor APIs that would have been modeled as a simple `GET` on the resource URL, but that are modeled as long-running operations due to MSGraph performance requirements, only the `Archive.Read.All` permission is necessary as long as creating the `archiveOperation` entity is \"safe\".\nHere, \"safe\" means that there are no side effects of creating the `archiveOperation` entity that would change the functionality of any entities outside of the `archive` being retrieved.\nThis requirment does not mean that the API must be idempotent, but an idempotent API is suffucient to meet this requirement.\n\n## When to use this pattern\n\nAny API call that is expected to take longer than one second in the 99th percentile should use the long running operations pattern.\n\nHow do you select which flavor of LRO pattern to use? An API designer can follow these heuristics:\n\n1. If a service can create a resource with a minimal latency and continue updating its status according to the well-defined and stable state transition model until completion, then the RELO model is the best choice.\n\n2. Otherwise, a service should follow the stepwise operation pattern.\n \n## Issues and considerations\n\n- One or more API consumers MUST be able to monitor and operate on the same resource at the same time.\n\n- The state of the system SHOULD always be discoverable and testable. Clients\n    SHOULD be able to determine the system state even if the operation tracking\n    resource is no longer active. Clients MAY issue a GET on some resource to\n    determine the state of a long running operation.\n\n- The long running operations pattern SHOULD work for clients looking to \"fire and forget\"\n    and for clients looking to actively monitor and act upon results.\n\n- The long running operations pattern might be supplemented by the [change notification pattern](./change-notification.md).\n\n- Cancellation of a long running operation does not explicitly mean a rollback. On a per API-defined case, it\n    might mean a rollback or compensation or completion or partial completion,\n    etc. Following a canceled operation, the API should return a consistent state that allows\n    continued service.\n\n- A recommended minimum retention time for a stepwise operation is 24 hours.\n    Operations SHOULD transition to \"tombstone\" for an additional period of time\n    prior to being purged from the system.\n    \n- Services that provide a new operation resource MUST support GET semantics on the operation.\n- Services that return a new operation MUST always return an LRO (even if the LRO is created in the completed state); that way API consumers don't have to deal with two different shapes of response.\n\n## Examples\n\n### Create a new resource using RELO\n\nA client wants to provision a new database:\n\n```\nPOST https://graph.microsoft.com/v1.0/storage/databases/\n\n{\n  \"displayName\": \"Retail DB\",\n}\n```\n\nThe API responds synchronously that the database has been created and indicates\nthat the provisioning operation is not fully completed by including the\nContent-Location header and status property in the response payload:\n\n```\nHTTP/1.1 201 Created\nLocation: https://graph.microsoft.com/v1.0/storage/databases/db1\n\n{\n  \"id\": \"db1\",\n  \"displayName\": \"Retail DB\",\n  \"status\": \"provisioning\",\n  [ … other fields for \"database\" …]\n}\n```\n\nThe client waits for a period of time, and then invokes another request to try to get the database status:\n\n```\nGET https://graph.microsoft.com/v1.0/storage/databases/db1\n\nHTTP/1.1 200 Ok\n{\n  \"id\": \"db1\",\n  \"displayName\": \"Retail DB\",\n  \"status\": \"succeeded\",\n  [ … other fields for \"database\" …]\n}\n```\n\n### Cancel RELO operation\n\nA client wants to cancel provisioning of a new database:\n\n```\nDELETE https://graph.microsoft.com/v1.0/storage/databases/db1\n\n```\n\nThe API responds synchronously that the database is being deleted and indicates\nthat the operation is accepted and is not fully completed by including the\nstatus property in the response payload. The API might provide a\nrecommendation to wait for 30 seconds:\n\n```\nHTTP/1.1 202 Accepted\nRetry-After: 30\n\n{\n  \"id\": \"db1\",\n  \"displayName\": \"Retail DB\",\n  \"status\": \"deleting\",\n  [ … other fields for \"database\" …]\n}\n```\n\nThe client waits for a period of time, and then invokes another request to try to get the deletion status:\n\n```\nGET https://graph.microsoft.com/v1.0/storage/databases/db1\n\nHTTP/1.1 404 Not Found\n```\n### Create a new resource using the stepwise operation\n\n```\nPOST https://graph.microsoft.com/v1.0/storage/archives/\n\n{\n  \"displayName\": \"Image Archive\",\n  ...\n}\n```\n\nThe API responds synchronously that the request has been accepted and includes\nthe Location header with an operation resource for further polling:\n\n```\nHTTP/1.1 202 Accepted\n\nLocation: https://graph.microsoft.com/v1.0/storage/operations/123\n\n```\n\n### Poll on a stepwise operation\n\n```\n\nGET https://graph.microsoft.com/v1.0/storage/operations/123\n```\n\nThe server responds that results are still not ready and optionally provides a\nrecommendation to wait 30 seconds:\n\n```\nHTTP/1.1 200 OK\nRetry-After: 30\n\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.4Z\",\n  \"lastActionDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"status\": \"running\"\n}\n```\n\nThe client waits the recommended 30 seconds and then invokes another request to get\nthe results of the operation:\n\n```\nGET https://graph.microsoft.com/v1.0/storage/operations/123\n```\n\n\nThe server responds with a \"status:succeeded\" operation that includes the resource\nlocation:\n\n```\nHTTP/1.1 200 OK\n\n{\n  \"createdDateTime\": \"2015-06-19T12-01-03.45Z\",\n  \"lastActionDateTime\": \"2015-06-19T12-06-03.0024Z\",\n  \"status\": \"succeeded\",\n  \"resourceLocation\": \"https://graph.microsoft.com/v1.0/storage/archives/987\"\n}\n```\n\n### Trigger a long running action using the stepwise operation\n\n```\nPOST https://graph.microsoft.com/v1.0/storage/copyArchive\n\n{\n  \"displayName\": \"Image Archive\",\n  \"destination\": \"Second-tier storage\"\n...\n}\n```\n\nThe API responds synchronously that the request has been accepted and includes\nthe Location header with an operation resource for further polling:\n\n```\nHTTP/1.1 202 Accepted\n\nLocation: https://graph.microsoft.com/v1.0/storage/operations/123\n\n```\n"
  },
  {
    "path": "graph/patterns/namespace.md",
    "content": "# Namespace\n\nMicrosoft Graph API Design Pattern\n\n*The namespace pattern provides the ability to organize resource definitions together into a logical set.*\n\n## Problem\n\nWhen building a complex offering, API designers might need to model many different\nresources and their relationships. For a better user experience and\ndiscoverability, related API elements need to be grouped together.  \n\n## Solution\n\nAPI designers can use the namespace attribute of the CSDL schema to declare a\nnamespace and logically organize related API entities in the Microsoft Graph metadata.\n\n```XML\n<Schema Namespace=\"microsoft.graph.{namespace}\" Alias=\"{namespace}\">\n...\n</Schema>\n```\n\nA public namespace must contain the `microsoft.graph.` prefix and be presented in camel\ncase; that is, `microsoft.graph.myNamespace`. Elements defined in namespaces not prefixed\nwith `microsoft.graph` will be mapped to the public `microsoft.graph` namespace.\n\nNamespaces should not include more than two segments following the `microsoft.graph` prefix;\nthat is, `microsoft.graph.myNamespace.mySubNamespace`. \n\nPublic namespaces must define an alias, and that alias must be the concatenation of \nthe segments following the `microsoft.graph` prefix with proper camel casing rules applied;\nthat is, `myNamespaceMySubNamespace`.\n\nWhen type casting is required in the API query, request, or response, a fully\nqualified type name is represented as concatenation of the namespace or alias, \nfollowed by a dot (`.`) and the type name. \n\n## When to use this pattern\n\nAPI resource grouping creates a user-friendly experience, keeping all resources for a specific feature close together and limiting the length of IDE prompts such as auto-complete in some programming languages.\n\nFor a consistent user experience, new namespace should be aligned with a top-level API category.\n\n## Issues and considerations\n\n- Microsoft Graph consistency requirements discourage using the same type names for different concepts even within different namespaces. Microsoft Graph type names must be descriptive and should represent a single concept across the API Surface.\n\n- A namespace must be consistent with an API category in the navigation path according to [Microsoft Graph REST API Guidelines](../GuidelinesGraph.md#uniform-resource-locators-urls).\n\n- Changing a namespace prefixed with `microsoft.graph`, or moving types between, into, or out of a namespace prefixed with `microsoft.graph`, is a breaking change.\n\n- To extend a type in a different schema, a service must declare that schema and the type in it. This is conceptually similar to .NET partial types.\n\n- To reference a type in a different schema, simply refer to that type by its fully qualified name (namespace + type name).\n\n- Cyclical references between namespaces are not allowed because many object-oriented languages don’t support cycles between namespaces.\n\n- Microsoft Graph has some predefined constraints for declared namespaces:\n\n  - All public namespaces must have the prefix `microsoft.graph`.\n\n  - Public namespaces must declare an alias that is the concatenation of the segments following the `microsoft.graph` prefix.\n\n  - At most, two levels of nesting below `microsoft.graph` is recommended.\n    \n  - If a namespace does not begin with the `microsoft.graph` prefix, all types in the schema are mapped into the public `microsoft.graph` namespace.\n\n## Examples\n\n### Namespace and type declarations\n\n```XML\n<Schema Namespace=\"microsoft.graph.search\" Alias=\"search\" xmlns=”<http://docs.oasis-open.org/odata/ns/edm>”\\>\n…\n    <EntityType Name=\"bookmark\" …\n    </EntityType>\n…\n</Schema>\n```\n\nFully qualified type name: `microsoft.graph.search.bookmark`\n\n### Managing multiple schemas\n\nWorkloads must define schemas in their CSDL by using the Edmx format.\nFollowing is an example of a workload that exposes multiple namespaces.\n\n> **Tip:** As with schemas that exist in the `microsoft.graph` namespace, defining an\nentity type is optional; by default your schema derives all entity types\nfrom `microsoft.graph.entity`.\n\n> **Warning:** Do not deviate from the general structure in the following example.\nThe schema validation tool expects the XML structure (including XML namespace\ndeclarations) to match this example.\n\n```XML\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http://docs.oasis-open.org/odata/ns/edmx\" xmlns:odata=\"http://schemas.microsoft.com/oDataCapabilities\">\n  <edmx:DataServices>\n    <Schema Namespace=\"microsoft.graph.callRecords\" Alias=\"callRecords\" xmlns=\"http://docs.oasis-open.org/odata/ns/edm\" xmlns:odata=\"http://schemas.microsoft.com/oDataCapabilities\">\n      <EntityType Name=\"callRecord\">\n        <Key>\n          <PropertyRef Name=\"id\" />\n        </Key>\n        <Property Name=\"version\" Type=\"Edm.Int64\" Nullable=\"false\" />\n        <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n      </EntityType>\n    </Schema>\n    <Schema Namespace=\"microsoft.graph\" xmlns=\"http://docs.oasis-open.org/odata/ns/edm\">\n      <EntityContainer Name=\"defaultContainer\">\n        <Singleton Name=\"communications\" Type=\"microsoft.graph.cloudCommunications\" />\n      </EntityContainer>\n      <EntityType Name=\"cloudCommunications\">\n        <Key>\n          <PropertyRef Name=\"id\" />\n        </Key>\n        <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n        <NavigationProperty Name=\"callRecords\" Type=\"Collection(microsoft.graph.callRecords.callRecord)\" ContainsTarget=\"true\" />\n      </EntityType>\n    </Schema>\n  </edmx:DataServices>\n</edmx:Edmx>\n```"
  },
  {
    "path": "graph/patterns/navigation-property.md",
    "content": "# Navigation Property\n\nMicrosoft Graph API Design Pattern\n\n*A navigation property is used to identify a relationship between resources.*\n\n## Problem\n--------\n\nIt is often valuable to represent a relationship between resources in an API. \n\nRelationships between resources are often implicitly represented by a property contained in one of the resources that provides a key to a related resource. Usually that information is returned in a representation as an id value and the property is named using a convention that identifies the target type of related resource. e.g. userId \n\nThe use of foreign key properties to describe related resources is a weakly typed mechanism and requires additional information for a developer to traverse the relationship. Discovery of related resources is not trivial.\n\n## Solution\n--------\n\nNavigation properties are an [OData convention](https://docs.microsoft.com/en-us/odata/webapi/model-builder-untyped#navigation-property) defined in the [CSDL Specification](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530365) that allows an API designer to describe a special kind of property in a model that references an related entity. In the HTTP API this property name translates to a path segment that can be appended to the URL of the primary resource in order to access a representation of the related resource. This prevents the client from needing to know any additional information on how to construct the URL to the related resource and the client does not need to retrieve the primary resource if it is only interested in the related resource.  It is the responsibility of the API implementation to determine the Id of the related resource and return the representation of the related entity. For example:\n\n     -  /user/{userId}/manager  represents many-to-one relationship\n     -  /user/{userId}/messages represents one-to-many relationship\n\nAdditionally, using the OData Expand query parameter, related entities can be nested into the primary entity so both can be retrieved in a single round trip.\n\nThese relationships can be described in CSDL as follows:\n\n```xml\n<EntityType Name=\"user\">\n  <NavigationProperty Name=\"manager\" Type=\"user\" ContainsTarget=\"false\" >\n  <NavigationProperty Name=\"messages\" Type=\"user\" ContainsTarget=\"true\" >\n</EntityType>\n```\n\n## Issues and Considerations\n-------------------------\n\nIn the current Microsoft Graph implementation, there are scenarios which use navigation properties that cross backend services that have automatic support; there are also some limitations for other scenarios. These limitations are being eliminated over time, but it will be necessary to ensure support for any particular scenario.  [Automatic support and limitations of the current implementation](https://dev.azure.com/msazure/One/_wiki/wikis/Microsoft%20Graph%20Partners/354352/Cross-workload-navigations?anchor=supported-scenarios) are documented internally.\n \nNavigation properties defined within an entity are not returned by default when retreiving the representation of an entity unless explicity desired by a service.  The API can consumer can use the `expand` query parameterm, where supported, to retreive both the source and the target entity of the relationship in a single request.\n\nImplementing support for accessing the \"$ref\" of a navigation property allows a caller to return just the URL of related resource. e.g. `/user/23/manager/$ref`. This is useful when a client wishes to identify the related resource but doesn't need all of its properties.\n\nThe strongly-typed nature of navigation properties is valuable for backend services and for client applications, when compared with the weakly-typed foreign key property.\nStrong typing allows some documentation and visualizations to be automatically generated, it allows SDK generation, and it allows some automated client code generation; it also prevents the need to store duplicate data on the service side and as a result has improved data consistency across APIs since the duplicate data does not need to be regularly refreshed. \n\n## When to Use this Pattern\n------------------------\n\n### \"Many-to-one\" relationships  \n\nThe use of navigation properties is preferred over including an Id field to reference the related entity in a many-to-one relationship.  Id values require a client to make two round trips to retrieve the details of a related entity.  With a navigation property a client can retrieve a related entity in a single round trip. \n \nMany-to-one relationships are always non-contained relationships as the lifetime of the target cannot depend on the source.\n\n```xml\n<EntityType Name=\"order\">\n  <NavigationProperty Name=\"customer\" Type=\"customer\" ContainsTarget=\"false\" >\n</EntityType>\n```\n\n\n### \"Zero-or-one-to-one\" relationships  \n\nThese navigation properties can be used as a structural organization mechanism to separate properties of an entity in a way that is similar to how complex types are often used. The primary difference being that the target of the navigation property are not returned by default when the source entity is retreived.  The use of the navigation properties over complex properties is preferred when the source and target information comes from different backend APIs.\n\nThese relationships must be contained.  \n\n```xml\n<EntityType Name=\"invoice\">\n  <NavigationProperty Name=\"paymentDetails\" Type=\"paymentInfo\" ContainsTarget=\"true\" >\n</EntityType>\n```\n\n### \"One-to-many\" relationships\n\nResources that contain a parent Id property in a child resource can utilize a navigation property in the parent resource that is declared as a collection of child resources. If desirable, a parent navigation property can also be created in the child resource to the parent resource. This is usually not necessary as the parent URL is a subset of child resource URL. The main use of this would be when retrieving child resources and choosing to expand properties of the parent resource so that both can be retrieved in a single request.  \n\n`/invoice/{invoiceId}/items/{itemId}?expand=parentInvoice(select=invoiceDate,Customer)`\n\n```xml\n<EntityType Name=\"invoice\">\n  <NavigationProperty Name=\"items\" Type=\"invoiceItem\" ContainsTarget=\"true\" >\n</EntityType>\n\n<EntityType Name=\"invoiceItem\">\n  <NavigationProperty Name=\"parentInvoice\" Type=\"invoice\" ContainsTarget=\"false\" >\n</EntityType>\n```\n\nOne-to-many relationships may be contained or non-contained relations.\n\n\n## Example\n-------\n\n### Retrieving a related entity\n\n```http\nGET /users/{id}/manager?$select=id,displayName\n\n200 OK\nContent-Type: application/json\n\n{\n  \"id\": \"6b3ee805-c449-46a8-aac8-8ff9cff5d213\",\n  \"displayName\": \"Bob Boyce\"\n}\n```\n\nThis navigation property could be described with the following CSDL: \n```xml\n<EntityType Name=\"user\">\n  <NavigationProperty Name=\"manager\" Type=\"graph.user\" ContainsTarget=\"false\" >\n</EntityType>\n```\n`ContainsTarget` is set to false for clarity, this is the default value when the attribute is omitted.\n### Retrieving a reference to a related entity\n\n```http\nGET /users/{id}/manager/$ref\n\n200 OK\nContent-Type: application/json\n\n{\n  \"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/6b3ee805-c449-46a8-aac8-8ff9cff5d213/Microsoft.DirectoryServices.User\"\n}\n```\nNote: Currently the base URL returned in $ref results are incorrect.  In order to process these URLs the client will need to convert the URL to a Graph URL.\n\n### Retrieving an entity with a related entity included\n\n```http\nGET /users/{id}?select=id,displayName&expand=manager(select=id,displayName)\n\n200 OK\nContent-Type: application/json\n\n{\n  \"id\": \"3f057904-f936-4bf0-9fcc-c1e6f84289d8\",\n  \"displayName\": \"Jim James\",\n  \"manager\": {\n    \"@odata.type\": \"#microsoft.graph.user\",\n    \"id\": \"6b3ee805-c449-46a8-aac8-8ff9cff5d213\",\n    \"displayName\": \"Bob Boyce\"\n  }\n}\n```\n\n### Creating an entity with a reference to a related entity\n\nCreate a new user that references an existing manager\n```http\nPOST /users\nContent-Type: application/json\n\n{\n    \"displayName\": \"Bob\",\n    \"manager@odata.bind\": \"https://graph.microsoft.com/v1.0/users/{managerId}\"\n}\n\n201 Created\n```\n\n### Updating a related entity reference\n\nUpdate the user entity to contain a relationship to an existing manager.\n \n```http\nPATCH /users/{id}\nContent-Type: application/json\n\n{\n    \"displayName\": \"Bob\",\n    \"manager@odata.bind\": \"https://graph.microsoft.com/v1.0/users/{managerId}\"\n}\n\n204 No Content\n```\n \n### Clear a related entity reference\n\nRemove the relationship between the user and the manager.\n \n```http\nDELETE /users/{id}/manager/$ref\n\n204 No Content\n```\n\nDelete the related entity.\n\n```http\nDELETE /users/{id}/manager\n\n204 No Content\n```\n"
  },
  {
    "path": "graph/patterns/operations.md",
    "content": "# Operations\n\nMicrosoft Graph API Design Pattern\n\n*The operations pattern provides the ability to model a change that might impact multiple resources and can't be effectively modeled by using HTTP methods.*\n\n## Problem\n\nSometimes when modeling a complex business domain, API designers need to model a business operation that effects one or multiple resources and has additional semantic meaning that cannot be expressed by HTTP methods. Modeling the operation via HTTP methods on each individual resource might be either inefficient or expose internal implementation details.\n\n## Solution\n\nTo address these use cases, API designers can use operational resources such as functions or actions. If the operation doesn't have any side effects and MUST return a single instance of a type or a collection of instances, then the designer SHOULD use OData functions; otherwise, the designer can model the operation as an action.\n\n## When to use this pattern\n\nThe operation pattern might be justified when a modeling operation represents one or combination of the following:\n\n- a change of a resource (i.e., increment the value of a property) rather than a state (i.e., the final value of the property)\n- complex processing logic that shouldn't be exposed to the client\n- operation parameters might convey a restricted set of option (i.e., a report that has to specify a date range)\n- the operation leverage some service-side data not exposed to (or easily retrieved in context by) the user.\n\nYou can consider related patterns such as [long running operations](./long-running-operations.md) and [change tracking](./change-tracking.md).\n\n## Issues and considerations\n\n- Microsoft Graph does NOT support unbound actions or functions. Bound actions and functions MUST must have the `isBound=\"true\"` attribute and a binding parameter. Bound operations are invoked on resources matching the type of the binding parameter.The first parameter of a bound operation is always the binding parameter.The binding parameter can be of any type, and parameter value MAY be Nullable.\n\n- Both actions and functions support overloading, meaning a schema might contain multiple actions or functions with the same name. The overload rules as per the OData [standard](http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_FunctionOverloads) apply when adding parameters to actions and functions.\n  \n- Because Microsoft Graph only supports bound actions and functions, all must have at least one parameter where the first is the binding parameter. The MUSTS of parameters are as follows:\n\n  - Each parameter must have a simple identifier name.\n  - The parameter name must be unique within the overload.\n  - The parameter must specify a type.\n\n- Microsoft Graph supports the use of optional parameters. The optional parameter annotation can be used instead of creating function or action overloads when unnecessary.\n\n- API designer **MUST** use POST to call actions on resources.\n- API designer **MUST** use GET to call functions on resources.\n\n- The addition of a new mandatory not-nullable parameter to an existing action or function is a breaking change and is not allowed without proper versioning that is in accordance with our [deprecation guidelines](https://github.com/microsoft/api-guidelines/blob/vNext/graph/deprecation.md).\n\n## Examples\n\n### A user wants to forward email\n\n```\nPOST https://graph.microsoft.com/v1.0/me/messages/AQMkADNkMmMxYzIwLWJkOTItNDczZC1hNmYyLWUwZjk2ZTljMDQyNQBGAAAD1dY5iRo4x0_pEqop6hOrQAcAeGCrbYV1-kiG-z9Rv6yHMgAAAgEJAAAAeGCrbYV1-kiG-z9Rv6yHMgABRxeUKgAAAA==/forward\n\n{\n    \"comment\": \"FYI\",\n    \"toRecipients\": [\n        {\n            \"emailAddress\": {\n                \"address\": \"alex.darrow@microsoft.com\",\n                \"name\": \"Alex Darrow\"\n            }\n        }\n    ]\n}\n```\nResponse:\n```\nHTTP/1.1 202 Accepted\n\n    \"cache-control\": \"private\",\n    \"client-request-id\": \"ca2d0416-a2c1-05af-df60-0921547a86e9\",\n    \"content-length\": \"0\",\n    \"request-id\": \"8b53016f-cc2b-4d9f-9818-bd6f0a5e3cd0\"\n```\n\n`forward` operation is modeled as an asynchronous action bound to the Graph `message` entity type because the operation represents a complex business logic processed on the server side. \n```\n<Action Name=\"forward\" IsBound=\"true\">\n        <Parameter Name=\"bindingParameter\" Type=\"graph.message\" />\n        <Parameter Name=\"ToRecipients\" Type=\"Collection(graph.recipient)\" />\n        <Parameter Name=\"Message\" Type=\"graph.message\" />\n        <Parameter Name=\"Comment\" Type=\"Edm.String\" Unicode=\"false\" />\n</Action>\n```\n\n### A user wants to see recent application activities\n\n```\nGET https://graph.microsoft.com/v1.0/me/activities/recent\n```\n\nResponse:\n\n```\nHTTP/1.1 200 OK\n\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#Collection(userActivity)\",\n    \"value\": []\n}\n```\n`recent` function will query the most recent historyItems and then pull related activities therefore the operation represents a complex business logic processed on the server side. This operation  doesn't change any server data and is a good fit for a function. The function is bound to the collection of `userActivity` entity type.\n\n```\n<Function Name=\"recent\" EntitySetPath=\"activities\" IsBound=\"true\">\n        <Parameter Name=\"bindingParameter\" Type=\"Collection(graph.userActivity)\" />\n        <ReturnType Type=\"Collection(graph.userActivity)\" />\n</Function>\n```\n### Get a report that provides the number of active users using Microsoft Edge\n\n```\nhttps://graph.microsoft.com/beta/reports/getBrowserUserCounts(period='D7')\n```\n\nResponse:\n\n```\nHTTP/1.1 200 OK\nContent-Type: application/json\nContent-Length: 205\n\n{\n   \"value\":[\n      {\n         \"reportRefreshDate\":\"2021-04-17\",\n         \"reportPeriod\":7,\n         \"userCounts\":[\n            {\n               \"reportDate\":\"2021-04-17\",\n               \"edge\":413\n            },\n            {\n               \"reportDate\":\"2021-04-16\",\n               \"edge\":883\n            }\n         ]\n      }\n   ]\n}\n```\n\n`getBrowserUserCounts` operation  doesn't change any server data and is a good fit for a function.`period` operation parameter convey a restricted set of options representing the number of days over which the report is aggregated. The report supports only 7,30,90, or 180 days. In addition the function doesn't return a Graph resource but streams response data in JSON or CSV formats.\n\n```\n<Function Name=\"getBrowserUserCounts\" IsBound=\"true\">\n        <Parameter Name=\"reportRoot\" Type=\"graph.reportRoot\" />\n        <Parameter Name=\"period\" Type=\"Edm.String\" Nullable=\"false\" Unicode=\"false\" />\n        <ReturnType Type=\"Edm.Stream\" Nullable=\"false\" />\n</Function>\n```\n"
  },
  {
    "path": "graph/patterns/subsets.md",
    "content": "# Modeling collection subsets\n\nMicrosoft Graph API Design Pattern\n\n*The modeling collection subsets pattern is the modeling state associated to a collection that may include all instances, an included subset, an excluded subset, no instances, or any combinations of the preceding items.*\n\n## Problem\n\nA common pattern is to apply a policy or state to a collection of resources. With this, there also comes the question of how to model cases where we want to apply to `all` or `none` without having to special case these values within the collection set or introduce cross-property dependencies. Likewise, we'd like to model it in a way where it is easy to understand and interpret usage from just looking at the schema.\n\nAn example is where you have a policy that you need to be able to apply to users in an organization. You might want to support the default **None**, enablement for **All**, or enablement for **Select** users where you only grant it to a few users.\n\nExisting patterns for this either have special-cased strings or have tightly coupled dependencies between two independent properties. Neither is intuitive, both require reading documentation, and neither can be inferred from the schema or within client libraries.\n\n## Solution\n\nHave an abstract base class where all variants of the subset are derived types from the base subset. For more information, see the [general subtyping guidance](./subtypes.md).\n\nThe abstract base class may also optionally hold an `enum` for the different variants. If it does, the `enum` must have a member for all possible variants. The purpose of including this is to allow for easier ways to do query and filter operations on variants like `all` and `none` without relying on `isof` functions.\n\n**Base type *without* an enum for the variants**\n\n```xml\n    <ComplexType Name=\"membershipBase\" IsAbstract=\"true\" />\n```\n\n**Base type *with* an enum for the variants**\n\n```xml\n    <ComplexType Name=\"membershipBase\" IsAbstract=\"true\">\n      <Property Name=\"membershipKind\" Type=\"graph.membershipKind\"/>\n    </ComplexType>\n\n    <EnumType Name=\"membershipKind\">\n      <Member Name=\"all\"/>\n      <Member Name=\"enumerated\"/>\n      <Member Name=\"none\"/>\n      <Member Name=\"unknownFutureValue\"/>\n    </EnumType>\n```\n\n**Derived types**\n\n```xml\n    <ComplexType Name=\"noMembership\" BaseType=\"graph.membershipBase\"/>\n\n    <ComplexType Name=\"allMembership\" BaseType=\"graph.membershipBase\"/>\n\n    <ComplexType Name=\"enumeratedMembership\" BaseType = \"graph.membershipBase\">\n      <Property Name=\"members\" Type=\"Collection(Edm.String)\"/>\n    </ComplexType>\n\n    <ComplexType Name=\"excludedMembership\" BaseType=\"graph.membershipBase\">\n      <Property Name=\"members\" Type=\"Collection(Edm.String)\"/>\n    </ComplexType>\n```\n\nBe aware that the name values and types in the preceding examples are just examples and can be replaced with your scenario equivalent values. For example, type names don't really need to be `memberships`. The collection doesn't have to be a collection at all; it can be singular and doesn't have to be a string.\n\nThese pattern type names should satisfy the following naming conventions:\n\n- The base type name should have the suffix `Base`, and the enumeration type name (if an `enum` is defined) should have the suffix `Kind`.\n- Derived child types should have names with enumeration values as the prefixes; for example, if the enumeration member value is `value1`, then the derived type name is `value1<type>`.\n\n```xml\n    <ComplexType Name=\"<type>Base\" IsAbstract=\"true\">\n      <Property Name=\"<type>Kind\" Type=\"graph.<type>Kind\"/>\n    </ComplexType>\n\n    <EnumType Name=\"<type>Kind\">\n      <Member Name=\"<value1>\"/>\n      <Member Name=\"<value2>\"/>\n      <Member Name=\"unknownFutureValue\"/>\n    </EnumType>\n\n    <ComplexType Name=\"value1<type>\" BaseType=\"graph.<type>Base\"/>\n\n    <ComplexType Name=\"value2<type>\" BaseType=\"graph.<type>Base\">\n      <Property Name=\"<property-name>\" Type=\"<property-type>\"/>\n    </ComplexType>\n```\n\n## When to use this pattern\n\nUse this pattern when supporting two or more collection states of the following, where at least one of the states is a subset variant:\n\n- All targets\n- No targets\n- Subset of targets to be included\n- Subset of targets to be excluded\n\nIf you only ever need to support two states&mdash;All or None&mdash;without using any subsets, it would be better to use a Boolean to toggle on and off.\n\n## Issues and considerations\n\nGiven that we are using an overarching subtype model, subtyping model limitations apply here as well; for more details, see the [subtyping documentation](./subtypes.md).\n\n## Example\n\n```http\nGET https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/\n```\n\n_Note: Unrelated properties on entities are omitted for easier readability._\n\n```json\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#conditionalAccessPolicy\",\n    \"values\": [\n        {\n            \"id\": \"66d36273-fe4c-d478-dc22-e0179d856ce7\",\n            \"conditions\": {\n                \"users\": {\n                    \"includeGuestsOrExternalUsers\": {\n                        \"externalTenants\": {\n                            \"@odata.type\":\"microsoft.graph.conditionalAccessAllExternalTenants\",\n                            \"membershipKind\": \"all\"\n                        }\n                    }\n                }\n            }\n        },\n        {\n            \"id\": \"99d212f4-d94e-cde1-8e3c-208d78238277\",\n            \"conditions\": {\n                \"users\": {\n                    \"includeGuestsOrExternalUsers\": {\n                        \"externalTenants\": {\n                            \"@odata.type\":\"microsoft.graph.conditionalAccessEnumeratedExternalTenants\",\n                            \"membershipKind\": \"enumerated\",\n                            \"members\": [\"bd005e2a-876d-4bf0-92a1-ae9ff4276d54\"]\n                        }\n                    }\n                }\n            }\n        }\n    ]\n}\n```\n\n```http\nPOST https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/\n```\n\n_Note: Unrelated properties on entities are omitted for easier readability._\n\n```json\n{\n    \"id\": \"66d36273-fe4c-d478-dc22-e0179d856ce7\",\n    \"conditions\": {\n        \"users\": {\n            \"includeGuestsOrExternalUsers\": {\n                \"externalTenants\": {\n                    \"@odata.type\":\"microsoft.graph.conditionalAccessAllExternalTenants\"\n                }\n            }\n        }\n    }\n}\n```\n\nor\n\n```http\nPOST https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/\n```\n\n_Note: Unrelated properties on entities are omitted for easier readability._\n\n```json\n{\n    \"id\": \"66d36273-fe4c-d478-dc22-e0179d856ce7\",\n    \"conditions\": {\n        \"users\": {\n            \"includeGuestsOrExternalUsers\": {\n                \"externalTenants\": {\n                    \"@odata.type\":\"microsoft.graph.conditionalAccessEnumeratedExternalTenants\",\n                    \"members\": [\"bd005e2a-876d-4bf0-92a1-ae9ff4276d54\"]\n                }\n            }\n        }\n    }\n}\n```\n\n### Filter when base type has the \"kind\" enum property\n\n```http\nGET https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies?$filter=conditions/users/includeGuestsOrExternalUsers/externalTenants/membershipKind eq 'all'\n\n200 OK\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#conditionalAccessPolicy\",\n    \"values\": [\n        {\n            \"id\": \"66d36273-fe4c-d478-dc22-e0179d856ce7\",\n            \"conditions\": {\n                \"users\": {\n                    \"includeGuestsOrExternalUsers\": {\n                        \"externalTenants\": {\n                            \"@odata.type\":\"microsoft.graph.conditionalAccessAllExternalTenants\",\n                            \"membershipKind\": \"all\"\n                        }\n                    }\n                }\n            }\n        }\n    ]\n}\n```\n\n### Filter when base type lacks the \"kind\" enum property\n\n```HTTP\nGET https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies?$filter=isof(conditions/users/includeGuestsOrExternalUsers/externalTenants, microsoft.graph.conditionalAccessAllExternalTenants)\n\n200 OK\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#conditionalAccessPolicy\",\n    \"values\": [\n        {\n            \"id\": \"66d36273-fe4c-d478-dc22-e0179d856ce7\",\n            \"conditions\": {\n                \"users\": {\n                    \"includeGuestsOrExternalUsers\": {\n                        \"externalTenants\": {\n                            \"@odata.type\":\"microsoft.graph.conditionalAccessAllExternalTenants\",\n                            \"membershipKind\": \"all\"\n                        }\n                    }\n                }\n            }\n        }\n    ]\n}\n```\n"
  },
  {
    "path": "graph/patterns/subtypes.md",
    "content": "# Type hierarchy\n\nMicrosoft Graph API Design Pattern\n\n*A frequent pattern in Microsoft Graph is to have a small type hierarchy, a base type with a few subtypes. This lets us model collections of resources that have slightly different properties and behavior.*\n\n## Problem\n\nThe API design requires that we model a set of resources based on a common concept\nthat can be further grouped into *mutually exclusive variants* with specific\nproperties and behaviors. The API design should be evolvable and allow the addition\nof new variants without breaking changes.\n\n## Solution\n\nAPI designers might use a *type hierarchy*, where there is one base\ntype (which might be abstract) with a few shared properties representing the common concept and one\nsubtype for each variant of the resource. In the hierarchy, the interdependencies of properties, that is, which properties are relevant for which variants, is fully captured in the type system.\n\n## When to use this pattern\n\nUse this pattern where each variant of a common concept has its own unique properties and behaviors,\nno combination of variants is anticipated, and it is acceptable that callers who need to query resources by variant are adequately served by filtering or partitioning using type casting.\n\nYou can consider related patterns such as [facets](./facets.md) and [flat bag of properties](./flat-bag.md).\n\n## Issues and considerations\n\nWhen introducing a new subtype to the hierarchy, developers need to ensure that\nthe new subtype doesn't change the semantic of the type hierarchy or collections of the specified base type with implicit constraints.\n\nTo reference properties specific to a derived type, an API request URL might need to include a segment casting to the derived type. If the type hierarchy is very deep, then the resulting URL might become very long and not easily readable.  \n\nThere are a few considerations to take into account when new subtypes are introduced:\n\n- *TODO add something about SDK dependencies and required actions*\n- *TODO* Client libraries for a strongly typed language might ignore some of the values\n    in the @odata.type property without further configuration and need to be\n    updated to be able to pick the right (client) type to deserialize into.\n- In the case of public APIs in GA versions, clients might develop their applications to support exclusively the current set of subtypes, and don’t expect new variations. To mitigate the risk of clients' disruption, when introducing a new subtype, allow ample time for communication and rollout.\n\n## Example\n\nThe directoryObject type is the main abstraction for many directory\ntypes such as users, organizational contacts, devices, service principals,\nand groups stored in Azure Active Directory. Because any directoryObject object is a unique entity, the directoryObject type itself is derived from the `graph.entity` base type.\n\n```XML\n<EntityType Name=\"entity\" Abstract=\"true\">\n    <Key>\n        <PropertyRef Name=\"id\" />\n    </Key>\n    <Property Name=\"id\" Type=\"Edm.String\" Nullable=\"false\" />\n</EntityType>\n<EntityType Name=\"directoryObject\" BaseType=\"graph.entity\" />\n    <Property Name=\"deletedDateTime\" Type=\"Edm.DateTimeOffset\" />\n<EntityType/>\n```\n\nGroups and users are derived types and modeled as follows:\n\n```XML\n <EntityType Name=\"group\" BaseType=\"graph.directoryObject\" />\n   <Property Name=\"description\" Type=\"Edm.String\" />\n   ...\n</EntityType>\n<EntityType Name=\"user\" BaseType=\"graph.directoryObject\">\n   <Property Name=\"jobTitle\" Type=\"Edm.String\" />\n   ...\n</EntityType>\n```\n\nAn API request to get members of a group returns a heterogeneous collection of\nusers and groups where each element can be a user or a group, and has an\nadditional `@odata.type` property that specifies the subtype:\n\n```\nGET https://graph.microsoft.com/v1.0/groups/a94a666e-0367-412e-b96e-54d28b73b2db/members\n\nResponse payload shortened for readability. The deletedDateTime property from the base type is a non-default property and is only returned if explicitly requested.\n\n{\n     \"@odata.context\":\n\"https://graph.microsoft.com/v1.0/$metadata#directoryObjects\",\n    \"value\": [\n        { \n            \"@odata.type\": \"#microsoft.graph.user\",\n            \"id\": \"37ca648a-a007-4eef-81d7-1127d9be34e8\",\n            \"jobTitle\": \"CEO\",\n            ...\n        },\n        {\n            \"@odata.type\": \"#microsoft.graph.group\",\n            \"id\": \"45f25951-d04f-4c44-b9b0-2a79e915658d\",\n            \"description\": \"Microsoft Graph API Reviewers\",\n            ...\n        },\n        ...        \n    ]\n}\n```\n\nAddressing a property of the subtype, for example, in `$filter` or `$select`, requires prefixing the property with the fully-qualified name of the subtype (or type derived from the subtype) on which it is defined. To filter on the `jobTitle` for the user type, you need to qualify the property with `microsoft.graph.user`. \n\nThe following query returns all groups that are members of group a94a666e-0367-412e-b96e-54d28b73b2db, as well as users that are members and whose jobTitle is CEO.\n\n```\nGET https://graph.microsoft.com/v1.0/groups/a94a666e-0367-412e-b96e-54d28b73b2db/members?$filter=microsoft.graph.user/jobTitle eq 'CEO'\n\nResponse payload shortened for readability:\n\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#directoryObjects\",\n    \"value\": [\n        {\n            \"@odata.type\": \"#microsoft.graph.user\",\n            \"id\": \"37ca648a-a007-4eef-81d7-1127d9be34e8\",\n            \"jobTitle\": \"CEO\",\n            ...\n        },\n        {\n            \"@odata.type\": \"#microsoft.graph.group\",\n            \"id\": \"45f25951-d04f-4c44-b9b0-2a79e915658d\",\n            \"description\": \"Microsoft Graph API Reviewers\",\n            ...\n        },\n       ...\n    ]\n}\n```\n\nAn entire collection can be cast to a particular subtype by appending the fully-qualified subtype name to the URL. Doing so filters the collection to members of (or derived from) that particular subtype, and makes the properties of that subtype available without casting. In this case, the `@odata.type` attribute is not returns for records of the specified subtype because the `@odata.context` indicates that the entire collection is consists of the particular subtype. Types derived from that subtype do still have the `@odata.type` attribute.\n\nThe following query returns only users that are members of group a94a666e-0367-412e-b96e-54d28b73b2db and whose jobTitle is CEO.\n\n```\nGET https://graph.microsoft.com/v1.0/groups/a94a666e-0367-412e-b96e-54d28b73b2db/members/microsoft.graph.user?$filter=jobTitle eq 'CEO'\n\nResponse payload shortened for readability:\n\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#users\",\n    \"value\": [\n        {\n            \"id\": \"37ca648a-a007-4eef-81d7-1127d9be34e8\",\n            \"jobTitle\": \"CEO\",\n            ...\n        },\n       ...\n    ]\n}\n```\n\nAn API request to create a subtype object in a polymorphic collection requires \"@odata.type\" specified in the request body.\n\n```\nPOST https://graph.microsoft.com/v1.0/directoryObjects\n\n{\n    \"@odata.type\": \"#microsoft.graph.group\",\n    \"description\": \"Microsoft Graph API Reviewers\",\n    ...\n}\n```\n"
  },
  {
    "path": "graph/patterns/upsert.md",
    "content": "# Upsert\n\nMicrosoft Graph API Design Pattern\n\n*The `Upsert` pattern is a non-destructive idempotent operation using a client-provided key, that ensures that system resources can be deployed in a reliable, repeatable, and controlled way, typically used in Infrastructure as Code (IaC) scenarios.*\n\n## Problem\n\nInfrastructure as code (IaC) defines system resources and topologies in a declarative manner that allows teams to manage those resources as they would code.\nPracticing IaC helps teams deploy system resources in a reliable, repeatable, and controlled way. \nIaC also helps automate deployment and reduces the risk of human error, especially for complex large environments. \nCustomers want to adopt IaC practices for many of the resources managed through Microsoft Graph.\n\nMost resources' creation operations in Microsoft Graph are not idempotent in nature.\nAs a consequence, API consumers that want to offer IaC solutions, must create compensation layers that can mimic idempotent behavior. \nFor example, when creating a resource, the compensation layer must check whether the resource first exists, before trying to create or update the resource.\n\nAdditionally, IaC code scripts or templates usually employ client-provided names (or keys) to track resources in a predictable manner, whereas [Microsoft Graph guidelines](../GuidelinesGraph.md#behavior-modeling) suggests use of `POST` to create new entities with service-generated keys.\n\n## Solution\n\nThe solution is to use an `Upsert` pattern, to solve for the non-idempotent creation and client-provided naming problems.\n\n* `Upsert` uses `PATCH` with a client-provided key in the URL:\n  * If there is a natural client-provided key that can serve as the primary key, then the service should support `Upsert` with that key.\n  * If the primary key is service-generated, the client-provided key should use an [alternate key](./alternate-key.md) to support idempotent creation.\n  * For a non-existent resource (specified by the client-provided key) the service must handle this as a \"create\" (aka insert). As part of creation, the service must still generate the primary key value, if appropriate.\n  * For an existing resource (specified by the client-provided key) the service must handle this as an \"update\".\n* If using an alternate key, then\n  * for IaC scenarios, the alternate key should be called `uniqueName`, if there isn't already a more natural existing property that could be used as an alternate key.\n  * the service must also support `GET` using the alternate key pattern.\n* Services should always support `POST` to the collection URL.\n  * For service-generated keys, this should return the server generated key.\n  * For client-provided keys, the client can provide the key as part of the request payload.\n* If a service does not support `Upsert`, then a `PATCH` call against a non-existent resource must result in an HTTP \"404 not found\" error.\n\nThis solution allows for existing resources that follow Microsoft Graph conventions for CRUD operations to add `Upsert` without impacting existing apps or functionality.\n\nIdeally, all new entity types should support an `Upsert` mechanism, especially where they support control-plane APIs, or are used in admin style or IaC scenarios.\n\n## When to use this pattern\n\nThis pattern should be adopted for resources that are managed through infrastructure as code or desired state configuration.\n\n## Issues and considerations\n\n* Services with existing APIs that use a client-defined key that want to start supporting the `Upsert` pattern may have concerns about backwards compatibility.\nAPI producers can require clients to opt-in to the `Upsert` pattern, by using the `Prefer: create-if-missing` HTTP request header.\n* `Upsert` can also be supported against singletons, using a `PATCH` to the singleton's URL.\n* Services that support `Upsert` should allow clients to use the:\n  * `If-Match=*` request header to explicitly treat an `Upsert` request as an update and not an insert.\n  * `If-None-Match=*` request header to explicitly treat an `Upsert` request as an insert and not an update.\n* The client-provided alternate key must be immutable after being set. If its value is null then it should be settable as a way to backfill existing resources for use in IaC scenarios.\n* API producers could use `PUT` operations to create or update, but generally this approach is not recommended due to the destructive nature of `PUT`'s replace semantics.\n* API producers may annotate entity sets, singletons and collections to indicate that entities can be \"upserted\". The example below shows this annotation for the `groups` entity set.  \n\n```xml\n<EntitySet Name=\"groups\" EntityType=\"microsoft.graph.group\">\n  <Annotation Term=\"Org.OData.Capabilities.V1.UpdateRestrictions\">\n    <Record>\n      <PropertyValue Property=\"Upsertable\" Bool=\"true\"/>\n    </Record>\n  </Annotation>\n</EntitySet>\n```\n\n## Examples\n\nFor these examples we'll use the `group` entity type, which defines both a primary (service-generated) key (`id`) and an alternate (client-provided) key (`uniqueName`). \n\n```xml\n<EntityType Name=\"group\">\n  <Key>\n    <PropertyRef Name=\"id\"/>\n  </Key>\n  <Property Name=\"id\" Type=\"Edm.String\"/> \n  <Property Name=\"uniqueName\" Type=\"Edm.String\"/>\n  <Property Name=\"displayName\" Type=\"Edm.String\"/>\n  <Property Name=\"description\" Type=\"Edm.String\"/> \n  <Annotation Term=\"Org.OData.Core.V1.AlternateKeys\">\n    <Collection>\n      <Record Type=\"Org.OData.Core.V1.AlternateKey\">\n        <PropertyValue Property=\"Key\">\n        <Collection>\n            <Record Type=\"Org.OData.Core.V1.PropertyRef\">\n            <PropertyValue Property=\"Name\" PropertyPath=\"uniqueName\" />\n            </Record>\n        </Collection>\n        </PropertyValue>\n      </Record>\n    </Collection>\n  </Annotation>\n  </Property>\n</EntityType>\n```\n\n### Upserting a record (creation path)\n\nCreate a new group, with a `uniqueName` of \"Group157\". In this case, this group does not exist.\n\n```http\nPATCH /groups(uniqueName='Group157')\nPrefer: return=representation\n```\n\n```json\n{\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\"\n}\n```\n\nResponse:\n\n```http\n201 created\nPreference-Applied: return=representation\n```\n\n```json\n{\n    \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\",\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\",\n    \"uniqueName\": \"Group157\"\n}\n```\n\n### Upserting a record (update path)\n\nCreate a new group, with a `uniqueName` of \"Group157\", exactly like before. Except in this case, this group already exists. This is a common scenario in IaC, when a deployment template is re-run multiple times.\n\n```http\nPATCH /groups(uniqueName='Group157')\nPrefer: return=representation\n```\n\n```json\n{\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\"\n}\n```\n\nResponse:\n\n```http\n200 ok\nPreference-Applied: return=representation\n```\n\n```json\n{\n    \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\",\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\",\n    \"uniqueName\": \"Group157\"\n}\n```\n\nNotice how this operation is idempotent in nature, rather than returning a 409 conflict error.\n\n### Updating a record\n\nUpdate \"Group157\" group with a new description.\n\n```http\nPATCH /groups(uniqueName='Group157')\nPrefer: return=representation\n```\n\n```json\n{\n    \"description\": \"Some of my favorite people in the world.\"\n}\n```\n\nResponse:\n\n```http\n200 ok\nPreference-Applied: return=representation\n```\n\n```json\n{\n    \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\",\n    \"displayName\": \"My favorite group\",\n    \"description\": \"Some of my favorite people in the world.\",\n    \"uniqueName\": \"Group157\"\n}\n```\n\n### Upsert opt-in request\n\nIn this case, the group API is a pre-existing API that supports `PATCH` with a client-provided alternate key. To enable `Upsert` behavior,\nthe client must opt-in using an HTTP request header, to create a new group using `PATCH`.\n\n```http\nPATCH /groups(uniqueName='Group157')\nPrefer: create-if-missing; return=representation\n```\n\n```json\n{\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\"\n}\n```\n\nResponse:\n\n```http\n201 created\nPreference-Applied: create-if-missing; return=representation\n```\n\n```json\n{\n    \"id\": \"1a89ade6-9f59-4fea-a139-23f84e3aef66\",\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\",\n    \"uniqueName\": \"Group157\"\n}\n```\n\n### Upsert (create) not supported\n\nFollowing on from the last example, the same request to create a new group, with a `uniqueName` of \"Group157\",\nwithout the opt-in header, results in a 404 HTTP response code.\n\n```http\nPATCH /groups(uniqueName='Group157')\nPrefer: return=representation\n```\n\n```json\n{\n    \"displayName\": \"My favorite group\",\n    \"description\": \"All my favorite people in the world\"\n}\n```\n\nResponse:\n\n```http\n404 not found\n```\n"
  },
  {
    "path": "graph/patterns/viewpoint.md",
    "content": "# Viewpoint\n\nMicrosoft Graph API Design Pattern\n\n\n*The viewpoint pattern provides the ability to manage properties of a shared object that have different values for different users.*\n\n## Problem\nA shared resource, such as a website or a group message, may have different states for different users who access it at different times in an organizational context. For example, user1 may read and delete a message, while user2 may not have seen it yet. This usually happens when a shared item is presented in an individual context.\n## Solution\n\nThe viewpoint pattern provides a solution to how to model an individual user context on a shared resource using a `viewpoint` structural property on an API entity type.\nFor example, the `viewpoint` property can indicate whether a message is read, deleted, or flagged for a given user. \nThe consistent naming convention ensures that when a developer uses Graph APIs all `viewpoint` structural properties represent type specific user context across different M365 services and features.\n\nThis pattern simplifies the API client logic by hiding the state transition details and providing state persistency on the server side. The server can manage the different viewpoints for the shared resource without exposing additional complexity to the client. To support queries for a user state the `viewpoint` property should support filtering.\n## Issues and considerations\n\n- Because the `viewpoint` property reflects an individual user's context, it is null when accessed with application permissions.\n- Sometimes, the viewpoint can be computed on the server. In this case, an API producer should add OData annotations to the property to provide more information for downstream tools, such as SDKs and documentation generation.\n```\n    <Annotations Target=\"microsoft.graph.approvalItem/viewPoint\">\n        <Annotation Term=\"Org.OData.Core.V1.Computed\" Bool=\"true\" />\n    </Annotations>\n```\n- An alternative to this design would be to store the user state on the client side. However, this may be problematic in some cases, because of the many devices that a user may have and the need to synchronize the state across them.\n- Often, updating the `viewpoint` property may cause a side effect, so you might consider an OData action to do the update. For some user scenarios, the `PATCH` method could be a better way to update a `viewpoint`.\n\n## Examples\n\n### Defining a viewpoint\n\nThe following example demonstrates how to define the 'viewpoint' property for the `chat` entity, where a chat is a collection of chatMessages between one or more participants: \n```\n  <ComplexType Name=\"chatViewpoint\" >\n        <Property Name=\"isHidden\" Type=\"Edm.Boolean\" />\n        <Property Name=\"lastMessageReadDateTime\" Type=\"Edm.DateTimeOffset\" />\n  </ComplexType>\n\n  <EntityType Name=\"chat\" BaseType=\"graph.entity\" >\n        <Property Name=\"chatType\" Type=\"graph.chatType\" Nullable=\"false\" />\n        <Property Name=\"createdDateTime\" Type=\"Edm.DateTimeOffset\" />\n        <Property Name=\"lastUpdatedDateTime\" Type=\"Edm.DateTimeOffset\" />              \n        <Property Name=\"topic\" Type=\"Edm.String\" />\n        <Property Name=\"viewpoint\" Type=\"graph.chatViewpoint\" />\n       ...\n        <NavigationProperty Name=\"tabs\" Type=\"Collection(graph.teamsTab)\" ContainsTarget=\"true\" />\n  </EntityType>\n\n```\n### Reading an entity with a viewpoint\n\nThe following example shows reading a collection of chats for an identified user, with a viewpoint for each chat:\n\n```http\nGET https://graph.microsoft.com/v1.0/users/8b081ef6-4792-4def-b2c9-c363a1bf41d5/chats\n```\n\n```http\n\nHTTP/1.1 200 OK\nContent-type: application/json\n```\n\n```\n{\n    \"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#chats\",\n    \"@odata.count\": 3,\n    \"value\": [\n        {\n            \"id\": \"19:meeting_MjdhNjM4YzUtYzExZi00OTFkLTkzZTAtNTVlNmZmMDhkNGU2@thread.v2\",\n            \"topic\": \"Meeting chat sample\",\n            \"createdDateTime\": \"2020-12-08T23:53:05.801Z\",\n            \"lastUpdatedDateTime\": \"2022-12-08T23:58:32.511Z\",\n            \"chatType\": \"meeting\",         \n            \"viewpoint\":{\n                \"lastMessageReadDateTime\": \"2021-03-28T21:10:00.000Z\"              \n            }\n        },\n        {\n            \"id\": \"19:561082c0f3f847a58069deb8eb300807@thread.v2\",\n            \"topic\": \"Group chat sample\",\n            \"createdDateTime\": \"2020-12-03T19:41:07.054Z\",\n            \"lastUpdatedDateTime\": \"2020-12-08T23:53:11.012Z\",\n            \"chatType\": \"group\",            \n            \"viewpoint\":{\n                \"lastMessageReadDateTime\": \"0000-01-01T00:00:00.000Z\"                \n            }\n        }\n    ]\n}\n```\n### Updating a viewpoint using an action\n\nThe following example shows marking a chat `viewpoint` as read for a user using an action:\n\n```http\n\nPOST https://graph.microsoft.com/beta/chats/19:7d898072-792c-4006-bb10-5ca9f2590649_8ea0e38b-efb3-4757-924a-5f94061cf8c2@unq.gbl.spaces/markChatReadForUser\n\n{\n \"user\": {\n    \"id\" : \"d864e79f-a516-4d0f-9fee-0eeb4d61fdc2\",\n    \"tenantId\": \"2a690434-97d9-4eed-83a6-f5f13600199a\"\n  }\n}\n```\n\nThe server responds with a  success status code and no payload:\n\n```http\nHTTP/1.1 204 No Content\n```\n### Updating a viewpoint using `PATCH` method\n\nThe following example shows how to mark a topic with the `viewpoint` label as reviewed for a user by using the `PATCH` method (this example does not represent an actual API, but only an illustration):\n\n```http\nPATCH https://graph.microsoft.com/beta/sampleTopics/19:7d898072-792c-4006-bb10-5ca9f259\n\n{  \n    \"title\": \"Announcements: Changes to PowerPoint and Word to open files faster\",\n    ...\n    \"viewpoint\": {\n         \"isReviewed\" : \"true\"\n    }\n}\n```\n\nThe server responds with a  success status code and no payload:\n\n```http\nHTTP/1.1 204 No Content\n```\n"
  },
  {
    "path": "license.txt",
    "content": "This work is licensed under the Creative Commons Attribution 4.0 International License.\nTo view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.\n"
  }
]