---
cuppy_hub: azure
cuppy_path: reference/cosmos-db/other-apis-and-documentdb.md
cuppy_section: docs
cuppy_doc: TC9A-YQ8N
cuppy_doc_uuid: bd070cb8-84b4-49b0-b73c-d276214256be
cuppy_permalink: https://cuppy.io/azure/d/TC9A-YQ8N
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/cosmos-db/other-apis-and-documentdb
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 775cdcdef5c5d05b4d9c2f7cb7b74cd4f8b8021c6d37e05edb01a1d9ff6e6ee8
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Cosmos DB's other APIs and Azure DocumentDB

| Need | Microsoft points to |
|---|---|
| Migrate a MongoDB app, or use MQL features | **Azure DocumentDB** (vCore clusters, formerly Cosmos DB for MongoDB vCore, built on the open-source DocumentDB project) |
| Global scale, 99.999% SLA, instant autoscale | Cosmos DB for NoSQL (`reference/cosmos-db/access-and-modeling.md`) |
| Migrate an Apache Cassandra app | **Azure Managed Instance for Apache Cassandra** rather than Cosmos DB for Apache Cassandra |
| Graph analytics, or migrate a Gremlin app | **Graph in Microsoft Fabric** rather than Cosmos DB for Apache Gremlin |

## Azure DocumentDB with Microsoft Entra

1. Allow Entra alongside native users first (keep `NativeAuth` until Entra sign-in works): `authConfig.allowedModes: ['NativeAuth', 'MicrosoftEntraID']` on `Microsoft.DocumentDB/mongoClusters` (the `documentdb` CLI extension's `mongocluster update` takes `--auth-allowed-modes`).
2. **Register each principal as a cluster user**: a `Microsoft.DocumentDB/mongoClusters/users` resource named `<cluster>/users/<object id>`, with `identityProvider.type: MicrosoftEntraID`, a `principalType` and roles such as `{"db": "sales", "role": "readWrite"}`, `readAnyDatabase`, `readWriteAnyDatabase` with `clusterAdmin`, or `{"db": "admin", "role": "root"}`.
3. Connect with **`MONGODB-OIDC`**; the token audience is the same as PostgreSQL's and MySQL's, `https://ossrdbms-aad.database.windows.net/.default`.

```ts
import { MongoClient, type OIDCCallbackParams, type OIDCResponse } from "mongodb";
import { DefaultAzureCredential, type TokenCredential } from "@azure/identity";

const SCOPE = "https://ossrdbms-aad.database.windows.net/.default"; // same audience as PostgreSQL and MySQL

async function entraToken(_params: OIDCCallbackParams, credential: TokenCredential): Promise<OIDCResponse> {
  const t = await credential.getToken(SCOPE);
  if (!t) throw new Error("no token");
  return { accessToken: t.token, expiresInSeconds: Math.floor((t.expiresOnTimestamp - Date.now()) / 1000) };
}

const credential = new DefaultAzureCredential();

// The identity must be registered as a cluster user (mongoClusters/users) with a role such as readWrite on the database.
export const client = new MongoClient(`mongodb+srv://${process.env.DOCUMENTDB_CLUSTER}.global.mongocluster.cosmos.azure.com/`, {
  tls: true,
  retryWrites: true,
  connectTimeoutMS: 120_000,
  authMechanism: "MONGODB-OIDC",
  authMechanismProperties: {
    OIDC_CALLBACK: (params: OIDCCallbackParams) => entraToken(params, credential),
    ALLOWED_HOSTS: ["*.azure.com"],
  },
});

export async function main(): Promise<void> {
  await client.connect();
  const orders = client.db("shop").collection<{ _id: string; customerId: string; total: number }>("orders");
  await orders.updateOne({ _id: "o-1001" }, { $set: { customerId: "c-42", total: 12.5 } }, { upsert: true });
  console.log(await orders.findOne({ _id: "o-1001" }));
  await client.close();
}
```

Deleting a principal in Entra doesn't remove the cluster user, and issued tokens stay valid until they expire (up to about 90 minutes): delete the `users/<object id>` resource to revoke at once. Storage can grow but never shrink. Some server-side MongoDB extensions and storage engines aren't supported.

## Cosmos DB for MongoDB (RU)

Endpoints are `<account>.mongo.cosmos.azure.com` (3.6 and later; 3.2 accounts used `documents.azure.com`), TLS 1.2. Its RBAC (users and roles, 3.6+) is managed only with the CLI or PowerShell.

| Code | Meaning → fix |
|---|---|
| **16500** TooManyRequests | RUs exhausted: retry, scale, or enable server-side retry |
| **50** ExceededTimeLimit | Past the 60-second limit: more RUs, smaller requests; retried writes can duplicate |
| **13** Unauthorized | Wrong key or missing permission |
| **11000** DuplicateKey | Unique index or shard key value already exists |
| **61** ShardKeyNotFound | The document lacks the shard (partition) key |
| **66** ImmutableField | Updating `_id` or the shard key |
| **2** BadValue | Sorting on a field without a matching (composite) index; or a multi-document transaction past 5 seconds |
| **67** CannotCreateIndex | Over 500 single-field indexes, or 8 fields in a compound index |
| **112** WriteConflict | Conflicting transactions: retry |
| **26** NamespaceNotFound | Database or collection name doesn't match |
| Socket / endOfStream errors | **Idle pooled connections are closed after about 4 minutes**: set `maxIdleTimeMS=120000` (Node.js: or `socketTimeoutMS` with keep-alive) |
| Old drivers can't find the account | Append `appName=@<account>@` to the connection string |

## Cosmos DB for Table

Has its own **native data-plane roles**, like NoSQL and distinct from Azure RBAC: Built-in Data Reader (`…0001`: `readMetadata`, entity read) and Built-in Data Contributor (`…0002`: `tables/*`, `tables/containers/entities/*`); `readMetadata` must always be allowed for SDK clients, and `notDataActions` isn't supported. Table storage in a storage account is a different service: `reference/storage/tables.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
