The Read API returns the tuples from a certain store that match a query filter specified in the body of the request.
The API doesn’t guarantee order by any field.
It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query.
In the body:
tuple_key is optional. If not specified, it returns all tuples in the store.
tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:).
tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id).
Examples
Query for all objects in a type definition
To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of
This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store.
The continuation token is empty if there are no more tuples to query.
Query for all stored relationship tuples that have a particular relation and object
To query for all users that have reader relationship with document:2021-budget, call read API with body of
This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them.
Query for all users with all relationships for a particular document
To query for all users that have any relationship with document:2021-budget, call read API with body of
using System.Collections.Generic;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Client.Model;
using OpenFga.Sdk.Model;
using Environment = System.Environment;
var fgaClient = new OpenFgaClient(new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"),
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"),
});
var body = new ClientReadRequest {
User = "user:anne",
Relation = "reader",
Object = "document:budget",
};
var options = new ClientReadOptions {
PageSize = 20,
};
var response = await fgaClient.Read(body, options);
import asyncio
import os
from openfga_sdk.client import OpenFgaClient, ClientConfiguration
from openfga_sdk import ReadRequestTupleKey
async def main():
configuration = ClientConfiguration(
api_url=os.environ.get("FGA_API_URL"),
store_id=os.environ.get("FGA_STORE_ID"),
)
async with OpenFgaClient(configuration) as fga_client:
body = ReadRequestTupleKey(
user="user:anne",
relation="reader",
object="document:budget",
)
options = {"page_size": 20}
response = await fga_client.read(body=body, options=options)
asyncio.run(main())
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.*;
import dev.openfga.sdk.api.client.model.*;
import dev.openfga.sdk.api.model.*;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import dev.openfga.sdk.api.configuration.ClientReadOptions;
public class Example {
public static void main(String[] args) throws Exception {
var config = new ClientConfiguration()
.apiUrl(System.getenv("FGA_API_URL"))
.storeId(System.getenv("FGA_STORE_ID"));
var fgaClient = new OpenFgaClient(config);
var body = new ClientReadRequest()
.user("user:anne")
.relation("reader")
._object("document:budget");
var options = new ClientReadOptions()
.pageSize(20);
var response = fgaClient.read(body, options).get();
}
}
# Set FGA_API_URL to the URL of your OpenFGA server.
# Set FGA_STORE_ID to your store ID.
# These examples use a server with authentication disabled.
# For authenticated servers, see /docs/getting-started/setup-sdk-client.
curl -X POST "$FGA_API_URL/stores/$FGA_STORE_ID/read" \
-H "content-type: application/json" \
-d '{
"tuple_key": {
"user": "user:anne",
"relation": "reader",
"object": "document:budget"
},
"page_size": 20
}'
using System.Collections.Generic;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Client.Model;
using OpenFga.Sdk.Model;
using Environment = System.Environment;
var fgaClient = new OpenFgaClient(new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"),
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"),
});
var body = new ClientReadRequest {
User = "user:anne",
Relation = "reader",
Object = "document:budget",
};
var options = new ClientReadOptions {
PageSize = 20,
};
var response = await fgaClient.Read(body, options);
import asyncio
import os
from openfga_sdk.client import OpenFgaClient, ClientConfiguration
from openfga_sdk import ReadRequestTupleKey
async def main():
configuration = ClientConfiguration(
api_url=os.environ.get("FGA_API_URL"),
store_id=os.environ.get("FGA_STORE_ID"),
)
async with OpenFgaClient(configuration) as fga_client:
body = ReadRequestTupleKey(
user="user:anne",
relation="reader",
object="document:budget",
)
options = {"page_size": 20}
response = await fga_client.read(body=body, options=options)
asyncio.run(main())
import dev.openfga.sdk.api.client.OpenFgaClient;
import dev.openfga.sdk.api.configuration.ClientConfiguration;
import dev.openfga.sdk.api.configuration.*;
import dev.openfga.sdk.api.client.model.*;
import dev.openfga.sdk.api.model.*;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import dev.openfga.sdk.api.configuration.ClientReadOptions;
public class Example {
public static void main(String[] args) throws Exception {
var config = new ClientConfiguration()
.apiUrl(System.getenv("FGA_API_URL"))
.storeId(System.getenv("FGA_STORE_ID"));
var fgaClient = new OpenFgaClient(config);
var body = new ClientReadRequest()
.user("user:anne")
.relation("reader")
._object("document:budget");
var options = new ClientReadOptions()
.pageSize(20);
var response = fgaClient.read(body, options).get();
}
}
# Set FGA_API_URL to the URL of your OpenFGA server.
# Set FGA_STORE_ID to your store ID.
# These examples use a server with authentication disabled.
# For authenticated servers, see /docs/getting-started/setup-sdk-client.
curl -X POST "$FGA_API_URL/stores/$FGA_STORE_ID/read" \
-H "content-type: application/json" \
-d '{
"tuple_key": {
"user": "user:anne",
"relation": "reader",
"object": "document:budget"
},
"page_size": 20
}'
{
"code": "throttled_timeout_error",
"message": "timeout due to throttling on complex request"
}
{
"code": "internal_error",
"message": "Internal Server Error"
}
{"docsConfig":{"theme":"luma","$schema":"https://mintlify.com/docs.json","name":"OpenFGA","description":"OpenFGA is a CNCF open source authorization system for fine-grained, relationship-based access control.","colors":{"primary":"#2c7a3f","light":"#d3ffd7","dark":"#558f69"},"logo":{"light":"https://raw.githubusercontent.com/openfga/community/22a5668e729b2d5453c6520e6f00c44a99fcd4fc/brand-assets/horizontal/color/black/openfga-horizontal-color_black.svg","dark":"https://raw.githubusercontent.com/openfga/community/22a5668e729b2d5453c6520e6f00c44a99fcd4fc/brand-assets/horizontal/color/white/openfga-horizontal-color_white.svg","href":"https://openfga.dev/"},"favicon":"https://mintcdn.com/fga/sFng5HcsvGPlDD3_/images/img/openfga-icon.svg?fit=max\u0026auto=format\u0026n=sFng5HcsvGPlDD3_\u0026q=85\u0026s=d48e6cd909aa0ce0d65f5dfe9085195d","api":{"playground":{"display":"simple"}},"appearance":{"default":"dark","strict":false},"background":{"color":{"dark":"#272b33"}},"navbar":{"links":[{"href":"/","label":"Docs"},{"href":"/api/service","label":"API Reference"},{"href":"https://openfga.dev/project","label":"Project"},{"href":"https://openfga.dev/community","label":"Community"},{"href":"https://openfga.dev/blog","label":"Blog"},{"href":"https://github.com/openfga/openfga","type":"github"}]},"footer":{"socials":{"x":"https://x.com/openfga","github":"https://github.com/openfga","linkedin":"https://www.linkedin.com/company/openfga","youtube":"https://www.youtube.com/@OpenFGA"}},"search":{"prompt":"Ask about OpenFGA"},"seo":{"metatags":{"canonical":"https://openfga.dev/docs","og:image":"https://openfga.dev/img/og-rich-embed.png","openfga:docs-source-sha256":"52615f566a33686f79387449f56e96ba38f4e369d945db11dcc3be3d69b9b373"},"indexing":"all"},"styling":{"codeblocks":"system","latex":false},"contextual":{"options":["copy","chatgpt","claude","add-mcp","cursor","vscode"],"display":"header"},"metadata":{"timestamp":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"fga","hasAudioNarration":false,"actualSubdomain":"fga","customDomains":["openfga.dev"],"gitSource":{"type":"github","owner":"openfga","repo":"openfga.dev","deployBranch":"docs-next","contentDirectory":"docs-site","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aba7c6a1d55b415c961eedb","collectionId":"f7d0c1ac-0b54-488f-8408-ed8af8fd6ab8","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aba7c6a1d55b415c961eedb"},"feedback":{"edits":true,"issues":true,"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ac3cb45308778e6590b59dc","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"Docs","count":110},{"language":"default","tag":"Modeling Guides","count":31},{"language":"default","tag":"API Reference","count":24},{"language":"default","tag":"Getting Started","count":22},{"language":"default","tag":"Interacting with the API","count":11},{"language":"default","tag":"Adopters","count":9},{"language":"default","tag":"Setup OpenFGA","count":8},{"language":"default","tag":"Industries","count":8},{"language":"default","tag":"Best Practices","count":7},{"language":"default","tag":"Learn","count":7}]},"assistantConfig":{},"basePath":"/docs","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"global.css","content":"@media (min-width:1024px){:root{--openfga-reader-width:100rem}#sidebar-content{width:16rem!important;left:max(0px,calc((100% - var(--assistant-sheet-width, 0px) - var(--openfga-reader-width))/2))}#body-content{max-width:var(--openfga-reader-width);margin-inline:auto;padding-left:16rem!important}#navbar>div:has(.topbar-right-container){max-width:var(--openfga-reader-width);margin-inline:auto}#content-container:not(:has(>[data-api-example])) #content-area{max-width:48rem;margin-inline:auto}}#content-container:has(>[data-api-example]) #content-area{margin-inline:auto}#navbar a[href='https://openfga.dev/'] img{width:6.3125rem;height:1.5rem;object-fit:contain}@media (min-width:1024px){#navbar div:has(>.topbar-right-container)>div:has(>a[href='https://openfga.dev/']){flex:0 0 auto}#navbar .topbar-right-container{min-width:0}#navbar .topbar-right-container>ul{flex:1}#navbar .topbar-right-container>ul>li:has(>a[href='https://github.com/openfga/openfga']){margin-left:auto}}@media (max-width:1023px){#navbar div:has(>.topbar-right-container){display:flex;position:absolute;top:0;right:1rem;width:2.25rem;padding:0}#navbar .topbar-right-container>div:has(>#search-bar-entry),#navbar .topbar-right-container>div:has(>button[aria-label='More actions']),#navbar .topbar-right-container>ul,#navbar div:has(>.topbar-right-container)>div:has(>a[href='https://openfga.dev/']){display:none}#navbar div:has(>#search-bar-entry-mobile){padding-right:3rem}}@layer utilities{@media (min-width:1100px){#navbar #search-bar-entry{width:clamp(9.25rem,16vw,16rem)!important;padding-inline:.875rem!important;justify-content:space-between!important}#navbar #search-bar-entry .truncate{display:block}#navbar #search-bar-entry>span{display:inline-flex}}}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ){position:relative;isolation:isolate;min-height:2.75rem;padding-inline:.75rem!important;background:0 0!important;border:0!important;border-radius:9999px!important;text-decoration:none!important}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n )::before{position:absolute;inset:.25rem 0;z-index:-1;content:'';background-color:transparent;border-radius:9999px;transition:background-color 150ms ease}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):is(:hover, :focus-visible)::before{background-color:rgb(0 0 0/5%)}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):is(:hover, :focus-visible){color:#1f2328!important}.dark #navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):is(:hover, :focus-visible)::before{background-color:rgb(255 255 255/8%)}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):focus-visible{outline:0}#navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):focus-visible::before{box-shadow:0 0 0 2px rgb(var(--primary))}.dark #navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):focus-visible::before{box-shadow:0 0 0 2px rgb(var(--primary-light))}.dark #navbar :is(\n a:is([href='/'], [href='/docs'], [href='/docs/']),\n a:is([href='/api/service'], [href='/docs/api/service']),\n a[href='https://openfga.dev/project'],\n a[href='https://openfga.dev/community'],\n a[href='https://openfga.dev/blog']\n ):is(:hover, :focus-visible){color:#f0f6fc!important}body:has(#api-playground-2-operation-page) #navbar a:is([href='/api/service'], [href='/docs/api/service']),body:not(:has(#api-playground-2-operation-page)) #navbar a:is([href='/'], [href='/docs'], [href='/docs/']){color:rgb(var(--primary))!important;font-weight:600}body:has(#api-playground-2-operation-page) #navbar a:is([href='/api/service'], [href='/docs/api/service'])::before,body:not(:has(#api-playground-2-operation-page)) #navbar a:is([href='/'], [href='/docs'], [href='/docs/'])::before{background-color:rgb(var(--primary)/10%)}.dark body:has(#api-playground-2-operation-page) #navbar a:is([href='/api/service'], [href='/docs/api/service']),.dark body:not(:has(#api-playground-2-operation-page)) #navbar a:is([href='/'], [href='/docs'], [href='/docs/']){color:rgb(var(--primary-light))!important}.dark body:has(#api-playground-2-operation-page) #navbar a:is([href='/api/service'], [href='/docs/api/service'])::before,.dark body:not(:has(#api-playground-2-operation-page)) #navbar a:is([href='/'], [href='/docs'], [href='/docs/'])::before{background-color:rgb(var(--primary-light)/12%)}.sidebar-group-header{text-transform:none}body:not(:has(#api-playground-2-operation-page)) #header .prose{display:none}.feedback-toolbar a[href^='https://github.com/openfga/']{min-height:3rem;gap:.375rem;padding:.25rem 0;border:0;border-radius:0;background:0 0;color:rgb(var(--primary));font-size:1rem;font-weight:400;line-height:1.65;text-decoration:none}.dark .feedback-toolbar a[href^='https://github.com/openfga/']{color:rgb(var(--primary-light))}.feedback-toolbar a[href^='https://github.com/openfga/']:hover{text-decoration:underline}.feedback-toolbar a[href^='https://github.com/openfga/']:focus-visible{outline:2px solid currentColor;outline-offset:4px;text-decoration:underline}.feedback-toolbar a[href^='https://github.com/openfga/'] small{font-size:inherit;line-height:inherit}.feedback-toolbar a[href^='https://github.com/openfga/'] svg{width:1.25rem;height:1.25rem;color:inherit}#footer div:has(>button[data-testid=mode-switch-system]),body:has(#api-playground-2-operation-page) .feedback-toolbar a[href^='https://github.com/openfga/openfga.dev/edit/'][href*='/docs-site/api/service/']{display:none}#ask-assistant-code-block-button,#assistant-entry,#assistant-entry-mobile,[data-assistant-bar],button[data-chat-payload-element-id]{display:none}#content .openfga-modeling-example{margin:2rem 0;padding:2rem;border-radius:1.5rem;background-color:#ebedf0;color:#1c1e21;font-family:'Inter',sans-serif}.dark #content .openfga-modeling-example{background-color:#444950;color:#e3e3e3}#content .openfga-modeling-example :is(ul, li, p, [data-as='p']){margin-block:0;font-size:14px;line-height:20px;letter-spacing:1.5px}#content .openfga-modeling-example ul{padding-left:2rem}#content .openfga-modeling-example hr{margin:1.5rem 0}#content .openfga-modeling-highlight{padding:1.2px 7.2px;border-radius:2.4px;font-family:'Inter',sans-serif;font-style:normal;font-weight:600;font-size:12px;line-height:18px;letter-spacing:.8px;text-transform:uppercase}a[href='https://github.com/openfga/openfga']>span:first-of-type{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.openfga-github-stars-fallback{display:inline-flex;align-items:center;gap:.375rem;margin-left:.25rem;flex-shrink:0}.openfga-github-stars-fallback__count{line-height:1rem}.openfga-github-stars-fallback__icon{width:.875rem;height:.875rem;background-color:currentColor;-webkit-mask:url(https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/star.svg) center/contain no-repeat;mask:url(https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/star.svg) center/contain no-repeat}.dark .shiki,.dark .shiki span{background-color:var(--shiki-dark-bg)!important;color:var(--shiki-dark)!important;font-style:var(--shiki-dark-font-style)!important;font-weight:var(--shiki-dark-font-weight)!important;text-decoration:var(--shiki-dark-text-decoration)!important}:root{--openfga-tabs-surface:#ffffff;--openfga-tabs-border:#d0d7de;--openfga-tabs-active:#1f2328;--openfga-tabs-inactive:#59636e;--openfga-tabs-accent:#1a7f37}.dark{--openfga-tabs-surface:#1c1e22;--openfga-tabs-border:#3a3d44;--openfga-tabs-active:#ffffff;--openfga-tabs-inactive:#a7b0bc;--openfga-tabs-accent:#79ed83}.openfga-code-viewer{--openfga-code-surface:#f6f8fa;--openfga-code-header:var(--openfga-tabs-surface);--openfga-code-border:var(--openfga-tabs-border);--openfga-code-default:#1f2328;--openfga-code-muted:#59636e;--openfga-code-keyword:#57606a;--openfga-code-type:#1a7f37;--openfga-code-relation:#0969da;--openfga-code-directly-assignable:#8250df;--openfga-code-error:#cf222e;--openfga-code-accent:#1a7f37;--openfga-json-key:#0969da;--openfga-json-string:#953800;--openfga-json-number:#0550ae;--openfga-json-keyword:#8250df;--openfga-json-punctuation:#57606a;overflow:hidden;color:var(--openfga-code-default);background:var(--openfga-code-surface);border:1px solid var(--openfga-code-border);border-radius:.5rem}.dark .openfga-code-viewer{--openfga-code-surface:var(--openfga-dark-background, #0b0c0e);--openfga-code-default:var(--openfga-dark-default, #ffffff);--openfga-code-muted:var(--openfga-tabs-inactive);--openfga-code-error:#ff7b72;--openfga-code-accent:var(--openfga-dark-accent, var(--openfga-tabs-accent));--openfga-json-key:#9cdcfe;--openfga-json-string:#ce9178;--openfga-json-number:#b5cea8;--openfga-json-keyword:#569cd6;--openfga-json-punctuation:#d4d4d4}.openfga-code-viewer__tabs{display:flex;background:var(--openfga-code-header);border-bottom:1px solid var(--openfga-code-border)}.openfga-code-viewer__tab{padding:.4rem 1rem;color:var(--openfga-code-muted);font-size:.85rem;font-weight:400;cursor:pointer;background:0 0;border:0;border-bottom:2px solid transparent}.openfga-code-viewer__tab[data-state=active]{color:var(--openfga-code-default);font-weight:600;border-bottom-color:var(--openfga-code-accent)}.openfga-code-viewer__tab:focus-visible{outline:2px solid var(--openfga-code-accent);outline-offset:-3px}.openfga-code-viewer__title{padding:.5rem 1rem;color:var(--openfga-code-muted);font-size:.8rem;background:var(--openfga-code-header);border-bottom:1px solid var(--openfga-code-border)}.openfga-code-viewer__status{padding:1rem;color:#59636e;background:0 0;border:0}.dark .openfga-code-viewer__status{color:#a7b0bc;background:0 0}.openfga-code-viewer__code{padding:1rem;margin:0;overflow-x:auto;color:var(--openfga-code-default);font-family:var(--font-mono, ui-monospace, monospace);font-size:.875rem;line-height:1.6;white-space:pre;background:var(--openfga-code-surface)}.openfga-code-token[data-token=comment]{color:var(--openfga-code-muted)}.openfga-code-token[data-token=condition-param-type],.openfga-code-token[data-token=keyword]{color:var(--openfga-code-keyword)}.openfga-code-token[data-token=condition],.openfga-code-token[data-token=extend],.openfga-code-token[data-token=module],.openfga-code-token[data-token=type]{color:var(--openfga-code-type)}.openfga-code-token[data-token=condition-param],.openfga-code-token[data-token=relation]{color:var(--openfga-code-relation)}.openfga-code-token[data-token=directly-assignable]{color:var(--openfga-code-directly-assignable)}.openfga-code-token[data-token=error]{color:var(--openfga-code-error)}.openfga-code-token[data-token=json-key]{color:var(--openfga-json-key)}.openfga-code-token[data-token=json-string]{color:var(--openfga-json-string)}.openfga-code-token[data-token=json-number]{color:var(--openfga-json-number)}.openfga-code-token[data-token=json-keyword]{color:var(--openfga-json-keyword)}.openfga-code-token[data-token=json-punctuation]{color:var(--openfga-json-punctuation)}.dark .openfga-code-viewer__code[data-language=dsl] .openfga-code-token:not([data-token=error]){color:var(--openfga-dark-token-color, var(--openfga-code-default, #ffffff))}"}],"page":{"pagePath":"api/service/relationship-tuples/get-stored-relationship-tuples","slug":"/api/service/relationship-tuples/get-stored-relationship-tuples","pageMetadata":{"title":"Get stored relationship tuples","description":"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. \nThe API doesn't guarantee order by any field. \nIt is different from the `/stores/{store_id}/expand` API in that it only returns relationship tuples that are stored in the system and satisfy the query. \nIn the body:\n1. `tuple_key` is optional. If not specified, it returns all tuples in the store.\n2. `tuple_key.object` is mandatory if `tuple_key` is specified. It can be a full object (e.g., `type:object_id`) or type only (e.g., `type:`).\n3. `tuple_key.user` is mandatory if tuple_key is specified in the case the `tuple_key.object` is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., `type:user_id`).\n\n## Examples\n\n### Query for all objects in a type definition\n\nTo query for all objects that `user:bob` has `reader` relationship in the `document` type definition, call read API with body of\n```json\n{\n \"tuple_key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:\"\n }\n}\n```\nThe API returns tuples and a continuation token, similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `user:bob` has a `reader` relationship with 1 document `document:2021-budget`. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store.\nThe continuation token is empty if there are no more tuples to query.\n\n### Query for all stored relationship tuples that have a particular relation and object\n\nTo query for all users that have `reader` relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\",\n \"relation\": \"reader\"\n }\n}\n```\nThe API returns something similar to: \n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`). Note that, even if the model said that all `writers` are also `readers`, the API does not return writers such as `user:anne` because it only returns tuples and does not evaluate them.\n\n### Query for all users with all relationships for a particular document\n\nTo query for all users that have any relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\"\n }\n}\n```\nThe API returns something similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:anne\",\n \"relation\": \"writer\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-05T13:42:12.356Z\"\n },\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`) and 1 `writer` (`user:anne`).\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/read","href":"/api/service/relationship-tuples/get-stored-relationship-tuples","autogeneratedByOpenApi":true,"hidden":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n h2: \"h2\",\n h3: \"h3\",\n li: \"li\",\n ol: \"ol\",\n p: \"p\",\n pre: \"pre\",\n span: \"span\",\n ..._provideComponents(),\n ...props.components\n }, {CodeBlock} = _components;\n if (!CodeBlock) _missingMdxReference(\"CodeBlock\", true);\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request.\\nThe API doesn’t guarantee order by any field.\\nIt is different from the \", _jsx(_components.code, {\n children: \"/stores/{store_id}/expand\"\n }), \" API in that it only returns relationship tuples that are stored in the system and satisfy the query.\\nIn the body:\"]\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"tuple_key\"\n }), \" is optional. If not specified, it returns all tuples in the store.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"tuple_key.object\"\n }), \" is mandatory if \", _jsx(_components.code, {\n children: \"tuple_key\"\n }), \" is specified. It can be a full object (e.g., \", _jsx(_components.code, {\n children: \"type:object_id\"\n }), \") or type only (e.g., \", _jsx(_components.code, {\n children: \"type:\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"tuple_key.user\"\n }), \" is mandatory if tuple_key is specified in the case the \", _jsx(_components.code, {\n children: \"tuple_key.object\"\n }), \" is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., \", _jsx(_components.code, {\n children: \"type:user_id\"\n }), \").\"]\n }), \"\\n\"]\n }), \"\\n\", _jsx(_components.h2, {\n children: \"Examples\"\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Query for all objects in a type definition\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"To query for all objects that \", _jsx(_components.code, {\n children: \"user:bob\"\n }), \" has \", _jsx(_components.code, {\n children: \"reader\"\n }), \" relationship in the \", _jsx(_components.code, {\n children: \"document\"\n }), \" type definition, call read API with body of\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"7\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"7\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuple_key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"user\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"user:bob\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"reader\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"The API returns tuples and a continuation token, similar to:\"\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"13\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"13\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuples\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": [\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" {\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"user\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"user:bob\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"reader\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"timestamp\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"2021-10-06T15:32:11.128Z\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" ],\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"continuation_token\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"This means that \", _jsx(_components.code, {\n children: \"user:bob\"\n }), \" has a \", _jsx(_components.code, {\n children: \"reader\"\n }), \" relationship with 1 document \", _jsx(_components.code, {\n children: \"document:2021-budget\"\n }), \". Note that this API, unlike the List Objects API, does not evaluate the tuples in the store.\\nThe continuation token is empty if there are no more tuples to query.\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Query for all stored relationship tuples that have a particular relation and object\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"To query for all users that have \", _jsx(_components.code, {\n children: \"reader\"\n }), \" relationship with \", _jsx(_components.code, {\n children: \"document:2021-budget\"\n }), \", call read API with body of\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"6\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"6\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuple_key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"reader\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"The API returns something similar to:\"\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"13\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"13\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuples\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": [\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" {\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"user\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"user:bob\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"reader\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"timestamp\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"2021-10-06T15:32:11.128Z\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" ],\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"continuation_token\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"This means that \", _jsx(_components.code, {\n children: \"document:2021-budget\"\n }), \" has 1 \", _jsx(_components.code, {\n children: \"reader\"\n }), \" (\", _jsx(_components.code, {\n children: \"user:bob\"\n }), \"). Note that, even if the model said that all \", _jsx(_components.code, {\n children: \"writers\"\n }), \" are also \", _jsx(_components.code, {\n children: \"readers\"\n }), \", the API does not return writers such as \", _jsx(_components.code, {\n children: \"user:anne\"\n }), \" because it only returns tuples and does not evaluate them.\"]\n }), \"\\n\", _jsx(_components.h3, {\n children: \"Query for all users with all relationships for a particular document\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"To query for all users that have any relationship with \", _jsx(_components.code, {\n children: \"document:2021-budget\"\n }), \", call read API with body of\"]\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"5\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"5\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuple_key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsx(_components.p, {\n children: \"The API returns something similar to:\"\n }), \"\\n\", _jsx(CodeBlock, {\n numberOfLines: \"21\",\n language: \"json\",\n children: _jsx(_components.pre, {\n className: \"shiki shiki-themes github-light-default dark-plus\",\n style: {\n backgroundColor: \"#ffffff\",\n \"--shiki-dark-bg\": \"#0B0C0E\",\n color: \"#1f2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n language: \"json\",\n children: _jsxs(_components.code, {\n language: \"json\",\n numberOfLines: \"21\",\n children: [_jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"{\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"tuples\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": [\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" {\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"user\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"user:anne\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"writer\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"timestamp\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"2021-10-05T13:42:12.356Z\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" {\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"key\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": {\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"user\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"user:bob\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"relation\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"reader\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \",\"\n })]\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"object\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"document:2021-budget\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" },\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"timestamp\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"2021-10-06T15:32:11.128Z\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" }\"\n })\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \" ],\"\n })\n }), \"\\n\", _jsxs(_components.span, {\n className: \"line\",\n children: [_jsx(_components.span, {\n style: {\n color: \"#116329\",\n \"--shiki-dark\": \"#9CDCFE\"\n },\n children: \" \\\"continuation_token\\\"\"\n }), _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \": \"\n }), _jsx(_components.span, {\n style: {\n color: \"#0A3069\",\n \"--shiki-dark\": \"#CE9178\"\n },\n children: \"\\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\"\"\n })]\n }), \"\\n\", _jsx(_components.span, {\n className: \"line\",\n children: _jsx(_components.span, {\n style: {\n color: \"#1F2328\",\n \"--shiki-dark\": \"#D4D4D4\"\n },\n children: \"}\"\n })\n }), \"\\n\"]\n })\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"This means that \", _jsx(_components.code, {\n children: \"document:2021-budget\"\n }), \" has 1 \", _jsx(_components.code, {\n children: \"reader\"\n }), \" (\", _jsx(_components.code, {\n children: \"user:bob\"\n }), \") and 1 \", _jsx(_components.code, {\n children: \"writer\"\n }), \" (\", _jsx(_components.code, {\n children: \"user:anne\"\n }), \").\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\nfunction _missingMdxReference(id, component) {\n throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");\n}\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"Get stored relationship tuples","description":"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. \nThe API doesn't guarantee order by any field. \nIt is different from the `/stores/{store_id}/expand` API in that it only returns relationship tuples that are stored in the system and satisfy the query. \nIn the body:\n1. `tuple_key` is optional. If not specified, it returns all tuples in the store.\n2. `tuple_key.object` is mandatory if `tuple_key` is specified. It can be a full object (e.g., `type:object_id`) or type only (e.g., `type:`).\n3. `tuple_key.user` is mandatory if tuple_key is specified in the case the `tuple_key.object` is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., `type:user_id`).\n\n## Examples\n\n### Query for all objects in a type definition\n\nTo query for all objects that `user:bob` has `reader` relationship in the `document` type definition, call read API with body of\n```json\n{\n \"tuple_key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:\"\n }\n}\n```\nThe API returns tuples and a continuation token, similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `user:bob` has a `reader` relationship with 1 document `document:2021-budget`. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store.\nThe continuation token is empty if there are no more tuples to query.\n\n### Query for all stored relationship tuples that have a particular relation and object\n\nTo query for all users that have `reader` relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\",\n \"relation\": \"reader\"\n }\n}\n```\nThe API returns something similar to: \n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`). Note that, even if the model said that all `writers` are also `readers`, the API does not return writers such as `user:anne` because it only returns tuples and does not evaluate them.\n\n### Query for all users with all relationships for a particular document\n\nTo query for all users that have any relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\"\n }\n}\n```\nThe API returns something similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:anne\",\n \"relation\": \"writer\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-05T13:42:12.356Z\"\n },\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`) and 1 `writer` (`user:anne`).\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/read","href":"/api/service/relationship-tuples/get-stored-relationship-tuples","autogeneratedByOpenApi":true,"hidden":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/fga/32b0a86692356b07/fga-codegen.js","/docs/_mintlify/custom/fga/16b8063137d7a263/openfga-dsl-highlight.js","/docs/_mintlify/custom/fga/9e516ad2628a4a37/github-star-cache.js","/docs/_mintlify/custom/fga/8f4f15cdd920fede/openfga-viewer.js","/docs/_mintlify/custom/fga/7e280f50d6626695/navbar-layout.js"],"openApiReferenceData":{"operation":{"description":"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. \nThe API doesn't guarantee order by any field. \nIt is different from the `/stores/{store_id}/expand` API in that it only returns relationship tuples that are stored in the system and satisfy the query. \nIn the body:\n1. `tuple_key` is optional. If not specified, it returns all tuples in the store.\n2. `tuple_key.object` is mandatory if `tuple_key` is specified. It can be a full object (e.g., `type:object_id`) or type only (e.g., `type:`).\n3. `tuple_key.user` is mandatory if tuple_key is specified in the case the `tuple_key.object` is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., `type:user_id`).\n\n## Examples\n\n### Query for all objects in a type definition\n\nTo query for all objects that `user:bob` has `reader` relationship in the `document` type definition, call read API with body of\n```json\n{\n \"tuple_key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:\"\n }\n}\n```\nThe API returns tuples and a continuation token, similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `user:bob` has a `reader` relationship with 1 document `document:2021-budget`. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store.\nThe continuation token is empty if there are no more tuples to query.\n\n### Query for all stored relationship tuples that have a particular relation and object\n\nTo query for all users that have `reader` relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\",\n \"relation\": \"reader\"\n }\n}\n```\nThe API returns something similar to: \n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`). Note that, even if the model said that all `writers` are also `readers`, the API does not return writers such as `user:anne` because it only returns tuples and does not evaluate them.\n\n### Query for all users with all relationships for a particular document\n\nTo query for all users that have any relationship with `document:2021-budget`, call read API with body of \n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\"\n }\n}\n```\nThe API returns something similar to:\n```json\n{\n \"tuples\": [\n {\n \"key\": {\n \"user\": \"user:anne\",\n \"relation\": \"writer\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-05T13:42:12.356Z\"\n },\n {\n \"key\": {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"timestamp\": \"2021-10-06T15:32:11.128Z\"\n }\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nThis means that `document:2021-budget` has 1 `reader` (`user:bob`) and 1 `writer` (`user:anne`).\n","operationId":"Read","parameters":["6c9cb363-0108-416f-a557-d6cff8ee25fa"],"requestBody":"7ca118ed-a149-4e1c-adda-c738d06f2f61","responses":{"200":"3c9690be-a1e4-4612-a5ea-e0c183bcecc3","400":"16c47f97-f8f5-43d1-a718-d7e9698ca029","401":"50734665-43be-4bbe-ba35-93ef7f7dde94","403":"5841cc4e-eec7-41d4-b6e3-3e93875a8086","404":"e263949b-893a-4682-abeb-35b101858821","409":"94e215f5-240d-4282-b7d5-1d599b56afa7","422":"3618d6ab-8c78-44f6-b8cd-e75b5c0b36cb","500":"5dff71a5-7c6b-4657-a6db-5a64524c0d6e"},"summary":"Get stored relationship tuples","tags":["Relationship Tuples"],"x-codeSamples":[{"lang":"node","label":"Node.js","source":"const { OpenFgaClient, ConsistencyPreference } = require('@openfga/sdk');\n\nconst fgaClient = new OpenFgaClient({\n apiUrl: process.env.FGA_API_URL,\n storeId: process.env.FGA_STORE_ID,\n});\n\nasync function main() {\n const body = {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"object\": \"document:budget\"\n };\n const options = {\n \"pageSize\": 20\n };\n const response = await fgaClient.read(body, options);\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});"},{"lang":"go","label":"Go","source":"package main\n\nimport (\n \"context\"\n \"os\"\n\n . \"github.com/openfga/go-sdk/client\"\n)\n\nfunc main() {\n fgaClient, err := NewSdkClient(\u0026ClientConfiguration{\n ApiUrl: os.Getenv(\"FGA_API_URL\"),\n StoreId: os.Getenv(\"FGA_STORE_ID\"),\n })\n if err != nil {\n panic(err)\n }\n \n pageSize := int32(20)\n user := \"user:anne\"\n relation := \"reader\"\n object := \"document:budget\"\n body := ClientReadRequest{\n User: \u0026user,\n Relation: \u0026relation,\n Object: \u0026object,\n }\n options := ClientReadOptions{\n PageSize: \u0026pageSize,\n }\n response, err := fgaClient.Read(context.Background()).Body(body).Options(options).Execute()\n if err != nil {\n panic(err)\n }\n _ = response\n}"},{"lang":"dotnet","label":".NET","source":"using System.Collections.Generic;\nusing OpenFga.Sdk.Client;\nusing OpenFga.Sdk.Client.Model;\nusing OpenFga.Sdk.Model;\nusing Environment = System.Environment;\n\nvar fgaClient = new OpenFgaClient(new ClientConfiguration() {\n ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"),\n StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"),\n});\n\nvar body = new ClientReadRequest {\n User = \"user:anne\",\n Relation = \"reader\",\n Object = \"document:budget\",\n};\nvar options = new ClientReadOptions {\n PageSize = 20,\n};\nvar response = await fgaClient.Read(body, options);"},{"lang":"python","label":"Python","source":"import asyncio\nimport os\nfrom openfga_sdk.client import OpenFgaClient, ClientConfiguration\nfrom openfga_sdk import ReadRequestTupleKey\n\nasync def main():\n configuration = ClientConfiguration(\n api_url=os.environ.get(\"FGA_API_URL\"),\n store_id=os.environ.get(\"FGA_STORE_ID\"),\n )\n async with OpenFgaClient(configuration) as fga_client:\n body = ReadRequestTupleKey(\n user=\"user:anne\",\n relation=\"reader\",\n object=\"document:budget\",\n )\n options = {\"page_size\": 20}\n response = await fga_client.read(body=body, options=options)\n\nasyncio.run(main())"},{"lang":"java","label":"Java","source":"import dev.openfga.sdk.api.client.OpenFgaClient;\nimport dev.openfga.sdk.api.configuration.ClientConfiguration;\nimport dev.openfga.sdk.api.configuration.*;\nimport dev.openfga.sdk.api.client.model.*;\nimport dev.openfga.sdk.api.model.*;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.ArrayList;\nimport dev.openfga.sdk.api.configuration.ClientReadOptions;\n\npublic class Example {\n public static void main(String[] args) throws Exception {\n var config = new ClientConfiguration()\n .apiUrl(System.getenv(\"FGA_API_URL\"))\n .storeId(System.getenv(\"FGA_STORE_ID\"));\n var fgaClient = new OpenFgaClient(config);\n \n var body = new ClientReadRequest()\n .user(\"user:anne\")\n .relation(\"reader\")\n ._object(\"document:budget\");\n var options = new ClientReadOptions()\n .pageSize(20);\n var response = fgaClient.read(body, options).get();\n }\n}"},{"lang":"bash","label":"curl","source":"# Set FGA_API_URL to the URL of your OpenFGA server.\n# Set FGA_STORE_ID to your store ID.\n# These examples use a server with authentication disabled.\n# For authenticated servers, see /docs/getting-started/setup-sdk-client.\n\ncurl -X POST \"$FGA_API_URL/stores/$FGA_STORE_ID/read\" \\\n -H \"content-type: application/json\" \\\n -d '{\n \"tuple_key\": {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"object\": \"document:budget\"\n },\n \"page_size\": 20\n}'"}],"method":"post","type":"path","servers":[],"security":[],"path":"/stores/{store_id}/read","baseUrlOptions":[],"title":"Get stored relationship tuples","codeSamples":[{"label":"Node.js","lang":"node","source":"const { OpenFgaClient, ConsistencyPreference } = require('@openfga/sdk');\n\nconst fgaClient = new OpenFgaClient({\n apiUrl: process.env.FGA_API_URL,\n storeId: process.env.FGA_STORE_ID,\n});\n\nasync function main() {\n const body = {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"object\": \"document:budget\"\n };\n const options = {\n \"pageSize\": 20\n };\n const response = await fgaClient.read(body, options);\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exitCode = 1;\n});"},{"label":"Go","lang":"go","source":"package main\n\nimport (\n \"context\"\n \"os\"\n\n . \"github.com/openfga/go-sdk/client\"\n)\n\nfunc main() {\n fgaClient, err := NewSdkClient(\u0026ClientConfiguration{\n ApiUrl: os.Getenv(\"FGA_API_URL\"),\n StoreId: os.Getenv(\"FGA_STORE_ID\"),\n })\n if err != nil {\n panic(err)\n }\n \n pageSize := int32(20)\n user := \"user:anne\"\n relation := \"reader\"\n object := \"document:budget\"\n body := ClientReadRequest{\n User: \u0026user,\n Relation: \u0026relation,\n Object: \u0026object,\n }\n options := ClientReadOptions{\n PageSize: \u0026pageSize,\n }\n response, err := fgaClient.Read(context.Background()).Body(body).Options(options).Execute()\n if err != nil {\n panic(err)\n }\n _ = response\n}"},{"label":".NET","lang":"dotnet","source":"using System.Collections.Generic;\nusing OpenFga.Sdk.Client;\nusing OpenFga.Sdk.Client.Model;\nusing OpenFga.Sdk.Model;\nusing Environment = System.Environment;\n\nvar fgaClient = new OpenFgaClient(new ClientConfiguration() {\n ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"),\n StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"),\n});\n\nvar body = new ClientReadRequest {\n User = \"user:anne\",\n Relation = \"reader\",\n Object = \"document:budget\",\n};\nvar options = new ClientReadOptions {\n PageSize = 20,\n};\nvar response = await fgaClient.Read(body, options);"},{"label":"Python","lang":"python","source":"import asyncio\nimport os\nfrom openfga_sdk.client import OpenFgaClient, ClientConfiguration\nfrom openfga_sdk import ReadRequestTupleKey\n\nasync def main():\n configuration = ClientConfiguration(\n api_url=os.environ.get(\"FGA_API_URL\"),\n store_id=os.environ.get(\"FGA_STORE_ID\"),\n )\n async with OpenFgaClient(configuration) as fga_client:\n body = ReadRequestTupleKey(\n user=\"user:anne\",\n relation=\"reader\",\n object=\"document:budget\",\n )\n options = {\"page_size\": 20}\n response = await fga_client.read(body=body, options=options)\n\nasyncio.run(main())"},{"label":"Java","lang":"java","source":"import dev.openfga.sdk.api.client.OpenFgaClient;\nimport dev.openfga.sdk.api.configuration.ClientConfiguration;\nimport dev.openfga.sdk.api.configuration.*;\nimport dev.openfga.sdk.api.client.model.*;\nimport dev.openfga.sdk.api.model.*;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.ArrayList;\nimport dev.openfga.sdk.api.configuration.ClientReadOptions;\n\npublic class Example {\n public static void main(String[] args) throws Exception {\n var config = new ClientConfiguration()\n .apiUrl(System.getenv(\"FGA_API_URL\"))\n .storeId(System.getenv(\"FGA_STORE_ID\"));\n var fgaClient = new OpenFgaClient(config);\n \n var body = new ClientReadRequest()\n .user(\"user:anne\")\n .relation(\"reader\")\n ._object(\"document:budget\");\n var options = new ClientReadOptions()\n .pageSize(20);\n var response = fgaClient.read(body, options).get();\n }\n}"},{"label":"curl","lang":"bash","source":"# Set FGA_API_URL to the URL of your OpenFGA server.\n# Set FGA_STORE_ID to your store ID.\n# These examples use a server with authentication disabled.\n# For authenticated servers, see /docs/getting-started/setup-sdk-client.\n\ncurl -X POST \"$FGA_API_URL/stores/$FGA_STORE_ID/read\" \\\n -H \"content-type: application/json\" \\\n -d '{\n \"tuple_key\": {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"object\": \"document:budget\"\n },\n \"page_size\": 20\n}'"}],"requiredOnlyExamples":false,"requestExampleType":"codeSamples","responseExampleType":"generated"},"dependencies":{"parameters":{"6c9cb363-0108-416f-a557-d6cff8ee25fa":{"in":"path","name":"store_id","required":true,"schema":{"type":"string","isRequired":true,"uniqueKey":"","typeLabel":"string"}}},"requestBody":{"content":{"application/json":{"schema":{"properties":{"consistency":{"type":"string","description":"Controls the consistency preference for this request. Default value is `UNSPECIFIED`, which has the same behavior as `MINIMIZE_LATENCY`.","default":"UNSPECIFIED","enum":["UNSPECIFIED","MINIMIZE_LATENCY","HIGHER_CONSISTENCY"],"example":"MINIMIZE_LATENCY","uniqueKey":"consistency","typeLabel":"enum\u003cstring>"},"continuation_token":{"example":"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==","type":"string","uniqueKey":"continuation_token","typeLabel":"string"},"page_size":{"example":50,"format":"int32","maximum":100,"minimum":1,"type":"integer","uniqueKey":"page_size","typeLabel":"integer\u003cint32>"},"tuple_key":{"properties":{"object":{"example":"document:2021-budget","maxLength":256,"type":"string","uniqueKey":"tuple_key.object","typeLabel":"string"},"relation":{"example":"reader","maxLength":50,"type":"string","uniqueKey":"tuple_key.relation","typeLabel":"string"},"user":{"example":"user:anne","maxLength":512,"type":"string","uniqueKey":"tuple_key.user","typeLabel":"string"}},"type":"object","uniqueKey":"tuple_key","typeLabel":"object"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"consistency":"MINIMIZE_LATENCY","continuation_token":"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==","page_size":50,"tuple_key":{"object":"document:2021-budget","relation":"reader","user":"user:anne"}}}},"exampleType":"generated"}},"required":true,"exampleType":"generated"},"responses":{"3c9690be-a1e4-4612-a5ea-e0c183bcecc3":{"content":{"application/json":{"schema":{"properties":{"continuation_token":{"description":"The continuation token is empty if there are no more tuples.","example":"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==","type":"string","isRequired":true,"uniqueKey":"continuation_token","typeLabel":"string"},"tuples":{"items":{"type":"object","required":["key","timestamp"],"properties":{"key":{"properties":{"object":{"example":"document:2021-budget","maxLength":256,"type":"string","isRequired":true,"uniqueKey":"tuples.items.[INDEX].key.object","typeLabel":"string"},"relation":{"example":"reader","maxLength":50,"type":"string","isRequired":true,"uniqueKey":"tuples.items.[INDEX].key.relation","typeLabel":"string"},"user":{"example":"user:anne","maxLength":512,"type":"string","isRequired":true,"uniqueKey":"tuples.items.[INDEX].key.user","typeLabel":"string"},"condition":{"properties":{"name":{"description":"A reference (by name) of the relationship condition defined in the authorization model.","example":"condition1","maxLength":256,"type":"string","isRequired":true,"uniqueKey":"tuples.items.[INDEX].key.condition.name","typeLabel":"string"},"context":{"description":"Additional context/data to persist along with the condition.\nThe keys must match the parameters defined by the condition, and the value types must\nmatch the parameter type definitions.","type":"object","uniqueKey":"tuples.items.[INDEX].key.condition.context","typeLabel":"object"}},"required":["name"],"type":"object","uniqueKey":"tuples.items.[INDEX].key.condition","typeLabel":"object"}},"required":["user","relation","object"],"type":"object","isRequired":true,"uniqueKey":"tuples.items.[INDEX].key","typeLabel":"object"},"timestamp":{"format":"date-time","type":"string","isRequired":true,"uniqueKey":"tuples.items.[INDEX].timestamp","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"tuples.items.[INDEX]","typeLabel":"object"},"type":"array","isRequired":true,"uniqueKey":"tuples","typeLabel":"object[]"}},"required":["tuples","continuation_token"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"continuation_token":"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==","tuples":[{"key":{"object":"document:2021-budget","relation":"reader","user":"user:anne","condition":{"name":"condition1","context":{}}},"timestamp":"2023-11-07T05:31:56Z"}]}}},"exampleType":"generated"}},"description":"A successful response.","exampleType":"generated"},"16c47f97-f8f5-43d1-a718-d7e9698ca029":{"content":{"application/json":{"schema":{"example":{"code":"validation_error","message":"Generic validation error"},"properties":{"code":{"default":"no_error","enum":["no_error","validation_error","authorization_model_not_found","authorization_model_resolution_too_complex","invalid_write_input","cannot_allow_duplicate_tuples_in_one_request","cannot_allow_duplicate_types_in_one_request","cannot_allow_multiple_references_to_one_relation","invalid_continuation_token","invalid_tuple_set","invalid_check_input","invalid_expand_input","unsupported_user_set","invalid_object_format","write_failed_due_to_invalid_input","authorization_model_assertions_not_found","latest_authorization_model_not_found","type_not_found","relation_not_found","empty_relation_definition","invalid_user","invalid_tuple","unknown_relation","store_id_invalid_length","assertions_too_many_items","id_too_long","authorization_model_id_too_long","tuple_key_value_not_specified","tuple_keys_too_many_or_too_few_items","page_size_invalid","param_missing_value","difference_base_missing_value","subtract_base_missing_value","object_too_long","relation_too_long","type_definitions_too_few_items","type_invalid_length","type_invalid_pattern","relations_too_few_items","relations_too_long","relations_invalid_pattern","object_invalid_pattern","query_string_type_continuation_token_mismatch","exceeded_entity_limit","invalid_contextual_tuple","duplicate_contextual_tuple","invalid_authorization_model","unsupported_schema_version","cancelled","invalid_start_time"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"validation_error","message":"Generic validation error"}}},"exampleType":"generated"}},"description":"Request failed due to invalid input.","exampleType":"generated"},"50734665-43be-4bbe-ba35-93ef7f7dde94":{"content":{"application/json":{"schema":{"example":{"code":"unauthenticated","message":"unauthenticated"},"properties":{"code":{"default":"no_error","enum":["no_error","validation_error","authorization_model_not_found","authorization_model_resolution_too_complex","invalid_write_input","cannot_allow_duplicate_tuples_in_one_request","cannot_allow_duplicate_types_in_one_request","cannot_allow_multiple_references_to_one_relation","invalid_continuation_token","invalid_tuple_set","invalid_check_input","invalid_expand_input","unsupported_user_set","invalid_object_format","write_failed_due_to_invalid_input","authorization_model_assertions_not_found","latest_authorization_model_not_found","type_not_found","relation_not_found","empty_relation_definition","invalid_user","invalid_tuple","unknown_relation","store_id_invalid_length","assertions_too_many_items","id_too_long","authorization_model_id_too_long","tuple_key_value_not_specified","tuple_keys_too_many_or_too_few_items","page_size_invalid","param_missing_value","difference_base_missing_value","subtract_base_missing_value","object_too_long","relation_too_long","type_definitions_too_few_items","type_invalid_length","type_invalid_pattern","relations_too_few_items","relations_too_long","relations_invalid_pattern","object_invalid_pattern","query_string_type_continuation_token_mismatch","exceeded_entity_limit","invalid_contextual_tuple","duplicate_contextual_tuple","invalid_authorization_model","unsupported_schema_version","cancelled","invalid_start_time"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"unauthenticated","message":"unauthenticated"}}},"exampleType":"generated"}},"description":"Not authenticated.","exampleType":"generated"},"5841cc4e-eec7-41d4-b6e3-3e93875a8086":{"content":{"application/json":{"schema":{"example":{"code":"forbidden","message":"the principal is not authorized to perform the action"},"properties":{"code":{"default":"no_auth_error","enum":["no_auth_error","auth_failed_invalid_subject","auth_failed_invalid_audience","auth_failed_invalid_issuer","invalid_claims","auth_failed_invalid_bearer_token","bearer_token_missing","unauthenticated","forbidden"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"forbidden","message":"the principal is not authorized to perform the action"}}},"exampleType":"generated"}},"description":"Forbidden.","exampleType":"generated"},"e263949b-893a-4682-abeb-35b101858821":{"content":{"application/json":{"schema":{"example":{"code":"undefined_endpoint","message":"Endpoint not enabled"},"properties":{"code":{"default":"no_not_found_error","enum":["no_not_found_error","undefined_endpoint","store_id_not_found","unimplemented"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"undefined_endpoint","message":"Endpoint not enabled"}}},"exampleType":"generated"}},"description":"Request failed due to incorrect path.","exampleType":"generated"},"94e215f5-240d-4282-b7d5-1d599b56afa7":{"content":{"application/json":{"schema":{"example":{"code":"10","message":"transaction conflict"},"properties":{"code":{"type":"string","uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"10","message":"transaction conflict"}}},"exampleType":"generated"}},"description":"Request was aborted due a transaction conflict.","exampleType":"generated"},"3618d6ab-8c78-44f6-b8cd-e75b5c0b36cb":{"content":{"application/json":{"schema":{"example":{"code":"throttled_timeout_error","message":"timeout due to throttling on complex request"},"properties":{"code":{"default":"no_throttled_error_code","enum":["no_throttled_error_code","throttled_timeout_error"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"throttled_timeout_error","message":"timeout due to throttling on complex request"}}},"exampleType":"generated"}},"description":"Request timed out due to excessive request throttling.","exampleType":"generated"},"5dff71a5-7c6b-4657-a6db-5a64524c0d6e":{"content":{"application/json":{"schema":{"example":{"code":"internal_error","message":"Internal Server Error"},"properties":{"code":{"default":"no_internal_error","enum":["no_internal_error","internal_error","deadline_exceeded","already_exists","resource_exhausted","failed_precondition","aborted","out_of_range","unavailable","data_loss"],"type":"string","uniqueKey":"code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"internal_error","message":"Internal Server Error"}}},"exampleType":"generated"}},"description":"Request failed due to internal server error.","exampleType":"generated"}},"security":{},"servers":{}},"originalFileLocation":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json"},"subdomain":"fga","siteName":"OpenFGA","title":"Get stored relationship tuples - OpenFGA","relatedPagesConfig":{"enabled":false,"limit":5,"mode":"automatic"},"navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-28T07:36:44.131Z","originalFileLocation":"api/service/relationship-tuples/get-stored-relationship-tuples.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. The API doesn\u0026#x27;t guarantee order by any field. It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query. In the body: 1. tuple_key is optional. If not specified, it returns all tuples in the store. 2. tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:). 3. tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id). ## Examples ### Query for all objects in a type definition To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:\u0026quot; } } The API returns tuples and a continuation token, similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store. The continuation token is empty if there are no more tuples to query. ### Query for all stored relationship tuples that have a particular relation and object To query for all users that have reader relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them. ### Query for all users with all relationships for a particular document To query for all users that have any relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:anne\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;writer\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-05T13:42:12.356Z\u0026quot; }, { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob) and 1 writer (user:anne).\">\u003cmeta data-mint-head name=\"application-name\" content=\"OpenFGA\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Get stored relationship tuples - OpenFGA\">\u003cmeta data-mint-head property=\"og:description\" content=\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. The API doesn\u0026#x27;t guarantee order by any field. It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query. In the body: 1. tuple_key is optional. If not specified, it returns all tuples in the store. 2. tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:). 3. tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id). ## Examples ### Query for all objects in a type definition To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:\u0026quot; } } The API returns tuples and a continuation token, similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store. The continuation token is empty if there are no more tuples to query. ### Query for all stored relationship tuples that have a particular relation and object To query for all users that have reader relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them. ### Query for all users with all relationships for a particular document To query for all users that have any relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:anne\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;writer\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-05T13:42:12.356Z\u0026quot; }, { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob) and 1 writer (user:anne).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"OpenFGA\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://openfga.dev/img/og-rich-embed.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Get stored relationship tuples - OpenFGA\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. The API doesn\u0026#x27;t guarantee order by any field. It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query. In the body: 1. tuple_key is optional. If not specified, it returns all tuples in the store. 2. tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:). 3. tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id). ## Examples ### Query for all objects in a type definition To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:\u0026quot; } } The API returns tuples and a continuation token, similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store. The continuation token is empty if there are no more tuples to query. ### Query for all stored relationship tuples that have a particular relation and object To query for all users that have reader relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them. ### Query for all users with all relationships for a particular document To query for all users that have any relationship with document:2021-budget, call read API with body of json { \u0026quot;tuple_key\u0026quot;: { \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; } } The API returns something similar to: json { \u0026quot;tuples\u0026quot;: [ { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:anne\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;writer\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-05T13:42:12.356Z\u0026quot; }, { \u0026quot;key\u0026quot;: { \u0026quot;user\u0026quot;: \u0026quot;user:bob\u0026quot;, \u0026quot;relation\u0026quot;: \u0026quot;reader\u0026quot;, \u0026quot;object\u0026quot;: \u0026quot;document:2021-budget\u0026quot; }, \u0026quot;timestamp\u0026quot;: \u0026quot;2021-10-06T15:32:11.128Z\u0026quot; } ], \u0026quot;continuation_token\u0026quot;: \u0026quot;eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\u0026quot; } This means that document:2021-budget has 1 reader (user:bob) and 1 writer (user:anne).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://openfga.dev/img/og-rich-embed.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/fga/Ogp9xKErjLVZVaSB/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"OpenFGA\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#2c7a3f\">\u003cmeta data-mint-head name=\"openfga:docs-source-sha256\" content=\"52615f566a33686f79387449f56e96ba38f4e369d945db11dcc3be3d69b9b373\">\u003clink data-mint-head rel=\"canonical\" href=\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/api/service/relationship-tuples/get-stored-relationship-tuples.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://openfga.dev/#organization\",\"name\":\"OpenFGA\",\"url\":\"https://openfga.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://raw.githubusercontent.com/openfga/community/22a5668e729b2d5453c6520e6f00c44a99fcd4fc/brand-assets/horizontal/color/black/openfga-horizontal-color_black.svg\"}},{\"@type\":\"WebSite\",\"@id\":\"https://openfga.dev/docs#website\",\"name\":\"OpenFGA\",\"url\":\"https://openfga.dev/docs\",\"publisher\":{\"@id\":\"https://openfga.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples#webpage\",\"url\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples\",\"name\":\"Get stored relationship tuples\",\"description\":\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. The API doesn't guarantee order by any field. It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query. In the body: 1. tuple_key is optional. If not specified, it returns all tuples in the store. 2. tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:). 3. tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id). ## Examples ### Query for all objects in a type definition To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of json { \\\"tuple_key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:\\\" } } The API returns tuples and a continuation token, similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store. The continuation token is empty if there are no more tuples to query. ### Query for all stored relationship tuples that have a particular relation and object To query for all users that have reader relationship with document:2021-budget, call read API with body of json { \\\"tuple_key\\\": { \\\"object\\\": \\\"document:2021-budget\\\", \\\"relation\\\": \\\"reader\\\" } } The API returns something similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them. ### Query for all users with all relationships for a particular document To query for all users that have any relationship with document:2021-budget, call read API with body of json { \\\"tuple_key\\\": { \\\"object\\\": \\\"document:2021-budget\\\" } } The API returns something similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:anne\\\", \\\"relation\\\": \\\"writer\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-05T13:42:12.356Z\\\" }, { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that document:2021-budget has 1 reader (user:bob) and 1 writer (user:anne).\",\"dateModified\":\"2026-09-28T07:36:44.131Z\",\"isPartOf\":{\"@id\":\"https://openfga.dev/docs#website\"},\"breadcrumb\":{\"@id\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Relationship Tuples\",\"item\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-all-tuple-changes\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Get stored relationship tuples\",\"item\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples#apireference\",\"headline\":\"Get stored relationship tuples\",\"name\":\"Get stored relationship tuples\",\"description\":\"The Read API returns the tuples from a certain store that match a query filter specified in the body of the request. The API doesn't guarantee order by any field. It is different from the /stores/{store_id}/expand API in that it only returns relationship tuples that are stored in the system and satisfy the query. In the body: 1. tuple_key is optional. If not specified, it returns all tuples in the store. 2. tuple_key.object is mandatory if tuple_key is specified. It can be a full object (e.g., type:object_id) or type only (e.g., type:). 3. tuple_key.user is mandatory if tuple_key is specified in the case the tuple_key.object is a type only. If tuple_key.user is specified, it needs to be a full object (e.g., type:user_id). ## Examples ### Query for all objects in a type definition To query for all objects that user:bob has reader relationship in the document type definition, call read API with body of json { \\\"tuple_key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:\\\" } } The API returns tuples and a continuation token, similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that user:bob has a reader relationship with 1 document document:2021-budget. Note that this API, unlike the List Objects API, does not evaluate the tuples in the store. The continuation token is empty if there are no more tuples to query. ### Query for all stored relationship tuples that have a particular relation and object To query for all users that have reader relationship with document:2021-budget, call read API with body of json { \\\"tuple_key\\\": { \\\"object\\\": \\\"document:2021-budget\\\", \\\"relation\\\": \\\"reader\\\" } } The API returns something similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that document:2021-budget has 1 reader (user:bob). Note that, even if the model said that all writers are also readers, the API does not return writers such as user:anne because it only returns tuples and does not evaluate them. ### Query for all users with all relationships for a particular document To query for all users that have any relationship with document:2021-budget, call read API with body of json { \\\"tuple_key\\\": { \\\"object\\\": \\\"document:2021-budget\\\" } } The API returns something similar to: json { \\\"tuples\\\": [ { \\\"key\\\": { \\\"user\\\": \\\"user:anne\\\", \\\"relation\\\": \\\"writer\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-05T13:42:12.356Z\\\" }, { \\\"key\\\": { \\\"user\\\": \\\"user:bob\\\", \\\"relation\\\": \\\"reader\\\", \\\"object\\\": \\\"document:2021-budget\\\" }, \\\"timestamp\\\": \\\"2021-10-06T15:32:11.128Z\\\" } ], \\\"continuation_token\\\": \\\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\\\" } This means that document:2021-budget has 1 reader (user:bob) and 1 writer (user:anne).\",\"url\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples\",\"mainEntityOfPage\":{\"@id\":\"https://openfga.dev/docs/api/service/relationship-tuples/get-stored-relationship-tuples#webpage\"},\"image\":\"https://openfga.dev/img/og-rich-embed.png\",\"dateModified\":\"2026-09-28T07:36:44.131Z\",\"publisher\":{\"@id\":\"https://openfga.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://openfga.dev/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"OpenFGA\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"OpenFGA","nav":{"global":null,"anchors":[{"anchor":"Docs","hidden":true,"pages":[{"title":"Docs","href":"/fga"}]},{"anchor":"API Reference","hidden":true,"groups":[{"group":"Stores","pages":[{"title":"List all stores","description":"Returns a paginated list of OpenFGA stores and a continuation token to get additional stores.\nThe continuation token is empty if there are no more stores.\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores","href":"/api/service/stores/list-all-stores"},{"title":"Create a store","description":"Create a unique OpenFGA store which is used to store authorization models and relationship tuples.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores","href":"/api/service/stores/create-a-store"},{"title":"Get a store","description":"Returns an OpenFGA store by its identifier","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores/{store_id}","href":"/api/service/stores/get-a-store"},{"title":"Delete a store","description":"Delete an OpenFGA store. This does not delete the data associated with the store, like tuples or authorization models.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json delete /stores/{store_id}","href":"/api/service/stores/delete-a-store"}]},{"group":"Authorization Models","pages":[{"title":"Get all authorization models","description":"The ReadAuthorizationModels API returns all the authorization models for a certain store.\nOpenFGA's response contains an array of all authorization models, sorted in descending order of creation.\n\n## Example\n\nAssume that a store's authorization model has been configured twice. To get all the authorization models that have been created in this store, call `GET authorization-models`. The API returns a response that looks like:\n\n```json\n{\n \"authorization_models\": [\n {\n \"id\": \"01G50QVV17PECNVAHX1GG4Y5NC\",\n \"type_definitions\": [...]\n },\n {\n \"id\": \"01G4ZW8F4A07AKQ8RHSVG9RW04\",\n \"type_definitions\": [...]\n },\n ],\n \"continuation_token\": \"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"\n}\n```\nIf there are no more authorization models available, then `continuation_token` field returns empty:\n\n```json\n{\n \"authorization_models\": [\n {\n \"id\": \"01G50QVV17PECNVAHX1GG4Y5NC\",\n \"type_definitions\": [...]\n },\n {\n \"id\": \"01G4ZW8F4A07AKQ8RHSVG9RW04\",\n \"type_definitions\": [...]\n },\n ],\n \"continuation_token\": \"\"\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores/{store_id}/authorization-models","href":"/api/service/authorization-models/get-all-authorization-models"},{"title":"Create a new authorization model","description":"The WriteAuthorizationModel API adds a new authorization model to a store.\nEach item in the `type_definitions` array is a type definition as specified in the field `type_definition`.\nThe response returns the authorization model's ID in the `id` field.\n\n## Example\n\nTo add an authorization model with `user` and `document` type definitions, call `POST` `authorization-models` API with the body: \n```json\n{\n \"type_definitions\":[\n {\n \"type\":\"user\"\n },\n {\n \"type\":\"document\",\n \"relations\":{\n \"reader\":{\n \"union\":{\n \"child\":[\n {\n \"this\":{}\n },\n {\n \"computedUserset\":{\n \"object\":\"\",\n \"relation\":\"writer\"\n }\n }\n ]\n }\n },\n \"writer\":{\n \"this\":{}\n }\n }\n }\n ]\n}\n```\nOpenFGA's response includes the version id for this authorization model, similar to:\n```\n{\"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\"}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/authorization-models","href":"/api/service/authorization-models/create-a-new-authorization-model"},{"title":"Get an authorization model by its ID","description":"The response returns the authorization model for the particular ID.\nAuthorization Models in OpenFGA are [immutable](/docs/getting-started/immutable-models), new versions can be created, but existing ones cannot be deleted or modified.\n\n## Example\n\nTo retrieve the authorization model with ID `01G5JAVJ41T49E9TT3SKVS7X1J` for the store, call the `GET` authorization-models by ID API with `01G5JAVJ41T49E9TT3SKVS7X1J` as the `id` path parameter. The API returns:\n```json\n{\n \"authorization_model\":{\n \"id\":\"01G5JAVJ41T49E9TT3SKVS7X1J\",\n \"type_definitions\":[\n {\n \"type\":\"user\"\n },\n {\n \"type\":\"document\",\n \"relations\":{\n \"reader\":{\n \"union\":{\n \"child\":[\n {\n \"this\":{}\n },\n {\n \"computedUserset\":{\n \"object\":\"\",\n \"relation\":\"writer\"\n }\n }\n ]\n }\n },\n \"writer\":{\n \"this\":{}\n }\n }\n }\n ]\n }\n}\n```\nIn the above example, there are 2 types (`user` and `document`). The `document` type has 2 relations (`writer` and `reader`).","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores/{store_id}/authorization-models/{id}","href":"/api/service/authorization-models/get-an-authorization-model-by-its-id"}]},{"group":"Relationship Tuples","pages":[{"title":"Get all tuple changes","description":"The ReadChanges API returns a paginated list of tuple changes (additions and deletions) that occurred in a given store, sorted by ascending time. The response includes a continuation token that is used to get the next set of changes. If there are no changes after the provided continuation token, the same token is returned in order for it to be used when new changes are recorded.\n\nIf the store never had any tuples added or removed, then this token returns empty.\nYou can use the `type` parameter to only get the list of tuple changes that affect objects of that type.\nWhen reading a write tuple change, if it was conditioned, the condition is returned.\nWhen reading a delete tuple change, the condition is NOT returned regardless of whether it was originally conditioned or not.\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores/{store_id}/changes","href":"/api/service/relationship-tuples/get-all-tuple-changes"},{"title":"Get stored relationship tuples","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/read","href":"/api/service/relationship-tuples/get-stored-relationship-tuples"},{"title":"Add or delete tuples","description":"The Write API transactionally updates the tuples for a certain store. Tuples and type definitions allow OpenFGA to determine whether a relationship exists between an object and an user.\n\nIn the body, `writes` adds new tuples and `deletes` removes existing tuples. When deleting a tuple, any `condition` specified with it is ignored.\n\nThe API is not idempotent by default: if, later on, you try to add the same tuple key (even if the `condition` is different), or if you try to delete a non-existing tuple, it throws an error.\n\nTo allow writes when an identical tuple already exists in the database, set `\"on_duplicate\": \"ignore\"` on the `writes` object.\nTo allow deletes when a tuple was already removed from the database, set `\"on_missing\": \"ignore\"` on the `deletes` object.\nIf a Write request contains both idempotent (ignore) and non-idempotent (error) operations, the most restrictive action (error) takes precedence. If a condition fails for a sub-request with an error flag, the entire transaction will be rolled back. This gives developers explicit control over the atomicity of the requests.\n\nThe API does not allow you to write tuples such as `document:2021-budget#viewer@document:2021-budget#viewer`, because they are implicit.\nAn `authorization_model_id` may be specified in the body. If it is, model ID is used to assert that each written tuple (not deleted) is valid for the model specified. If it is not specified, the latest authorization model ID is used.\n\n## Example\n\n### Adding relationships\n\nTo add `user:anne` as a `writer` for `document:2021-budget`, call write API with the following:\n```json\n{\n \"writes\": {\n \"tuple_keys\": [\n {\n \"user\": \"user:anne\",\n \"relation\": \"writer\",\n \"object\": \"document:2021-budget\"\n }\n ],\n \"on_duplicate\": \"ignore\"\n },\n \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\"\n}\n```\n### Removing relationships\n\nTo remove `user:bob` as a `reader` for `document:2021-budget`, call write API with the following:\n```json\n{\n \"deletes\": {\n \"tuple_keys\": [\n {\n \"user\": \"user:bob\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n }\n ],\n \"on_missing\": \"ignore\"\n }\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/write","href":"/api/service/relationship-tuples/add-or-delete-tuples"}]},{"group":"Relationship Queries","pages":[{"title":"Check multiple authorizations in a single request","description":"The `BatchCheck` API functions nearly identically to `Check`, but instead of checking a single user-object relationship BatchCheck accepts a list of relationships to check and returns a map containing `BatchCheckItem` response for each check it received.\n\nAn associated `correlation_id` is required for each check in the batch. This ID is used to correlate a check to the appropriate response. It is a string consisting of only alphanumeric characters or hyphens with a maximum length of 36 characters. This `correlation_id` is used to map the result of each check to the item which was checked, so it must be unique for each item in the batch. We recommend using a UUID or ULID as the `correlation_id`, but you can use whatever unique identifier you need as long as it matches this regex pattern: `^[\\w\\d-]{1,36}$`\n\n> **Note:** The maximum number of checks that can be passed in the `BatchCheck` API is configurable using the environment variable: `[OPENFGA_MAX_CHECKS_PER_BATCH_CHECK](https://openfga.dev/docs/getting-started/setup-openfga/configuration#OPENFGA_MAX_CHECKS_PER_BATCH_CHECK)`. If `BatchCheck` is called using the SDK, the SDK can split the batch check requests for you.\n\nFor more details on how `Check` functions, review the docs for `/check`.\n\n### Examples\n\n#### A BatchCheckRequest\n```json\n{\n \"checks\": [\n {\n \"tuple_key\": {\n \"object\": \"document:2021-budget\"\n \"relation\": \"reader\",\n \"user\": \"user:anne\",\n },\n \"contextual_tuples\": {...}\n \"context\": {}\n \"correlation_id\": \"01JA8PM3QM7VBPGB8KMPK8SBD5\"\n },\n {\n \"tuple_key\": {\n \"object\": \"document:2021-budget\"\n \"relation\": \"reader\",\n \"user\": \"user:bob\",\n },\n \"contextual_tuples\": {...}\n \"context\": {}\n \"correlation_id\": \"01JA8PMM6A90NV5ET0F28CYSZQ\"\n }\n ]\n}\n```\n\nBelow is a possible response to the above request. Note that the result map's keys are the `correlation_id` values from the checked items in the request:\n```json\n{\n \"result\": {\n \"01JA8PMM6A90NV5ET0F28CYSZQ\": {\n \"allowed\": false, \n \"error\": {\"message\": \"\"} \n },\n \"01JA8PM3QM7VBPGB8KMPK8SBD5\": {\n \"allowed\": true, \n \"error\": {\"message\": \"\"} \n }\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/batch-check","href":"/api/service/relationship-queries/check-multiple-authorizations-in-a-single-request"},{"title":"Check user authorization","description":"The Check API returns whether a given user has a relationship with a given object in a given store.\n\nThe `user` field of the request can be a specific target, such as `user:anne`, or a userset (set of users) such as `group:marketing#member` or a type-bound public access `user:*`.\nTo arrive at a result, the API uses:\n\n- An [authorization model](/docs/getting-started/configure-model)\n\n- Explicit tuples written through the Write API\n\n- Contextual tuples present in the request\n\n- Implicit tuples that exist by virtue of applying set theory\n\nFor example: `document:2021-budget#viewer@document:2021-budget#viewer`. In this example, the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`.\n\nA `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`.\nYou may also provide an `authorization_model_id` in the body. This is used to assert that the input `tuple_key` is valid for the model specified. If not specified, the assertion is made against the latest authorization model ID.\n\n> **Note:** We recommend you specify authorization model id for better performance.\n\nYou may also provide a `context` object that is used to evaluate the conditioned tuples in the system.\n\n> **Note:** We recommend you provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly.\n\nBy default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency.\nThe response returns whether the relationship exists in the field `allowed`.\n\nSome exceptions apply, but in general, if a Check API responds with `{allowed: true}`, then you can expect the equivalent ListObjects query to return the object, and viceversa. \nFor example, if `Check(user:anne, reader, document:2021-budget)` responds with `{allowed: true}`, then `ListObjects(user:anne, reader, document)` may include `document:2021-budget` in the response.\n## Examples\n\n### Querying with contextual tuples\n\nIn order to check if user `user:anne` of type `user` has a `reader` relationship with object `document:2021-budget` given the following contextual tuple:\n```json\n{\n \"user\": \"user:anne\",\n \"relation\": \"member\",\n \"object\": \"time_slot:office_hours\"\n}\n```\nthe Check API can be used with the following request body:\n```json\n{\n \"tuple_key\": {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"contextual_tuples\": {\n \"tuple_keys\": [\n {\n \"user\": \"user:anne\",\n \"relation\": \"member\",\n \"object\": \"time_slot:office_hours\"\n }\n ]\n },\n \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\"\n}\n```\n### Querying usersets\n\nSome Checks always return `true`, even without any tuples. For example, for the following authorization model:\n```python\nmodel\n schema 1.1\ntype user\ntype document\n relations\n define reader: [user]\n```\nthe following query:\n```json\n{\n \"tuple_key\": {\n \"user\": \"document:2021-budget#reader\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n }\n}\n```\nalways returns `{ \"allowed\": true }`. This is because usersets are self-defining: the userset `document:2021-budget#reader` always has the `reader` relation with `document:2021-budget`.\n### Querying usersets with difference in the model\n\nA Check for a userset can yield results that must be treated carefully if the model involves difference. For example, for the following authorization model:\n```python\nmodel\n schema 1.1\ntype user\ntype group\n relations\n define member: [user]\ntype document\n relations\n define blocked: [user]\n define reader: [group#member] but not blocked\n```\nthe following query:\n```json\n{\n \"tuple_key\": {\n \"user\": \"group:finance#member\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"contextual_tuples\": {\n \"tuple_keys\": [\n {\n \"user\": \"user:anne\",\n \"relation\": \"member\",\n \"object\": \"group:finance\"\n },\n {\n \"user\": \"group:finance#member\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n {\n \"user\": \"user:anne\",\n \"relation\": \"blocked\",\n \"object\": \"document:2021-budget\"\n }\n ]\n },\n}\n```\nreturns `{ \"allowed\": true }`, even though a specific user of the userset `group:finance#member` does not have the `reader` relationship with the given object.\n### Requesting higher consistency\n\nBy default, the Check API caches results for a short time to optimize performance. You may request higher consistency to inform the server that higher consistency should be preferred at the expense of increased latency. Care should be taken when requesting higher consistency due to the increased latency.\n```json\n{\n \"tuple_key\": {\n \"user\": \"group:finance#member\",\n \"relation\": \"reader\",\n \"object\": \"document:2021-budget\"\n },\n \"consistency\": \"HIGHER_CONSISTENCY\"\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/check","href":"/api/service/relationship-queries/check-user-authorization"},{"title":"Expand relationships in userset tree format","description":"The Expand API returns all users and usersets that have certain relationship with an object in a certain store.\nThis is different from the `/stores/{store_id}/read` API in that both users and computed usersets are returned.\n\nBody parameters `tuple_key.object` and `tuple_key.relation` are all required.\nA `contextual_tuples` object may also be included in the body of the request. This object contains one field `tuple_keys`, which is an array of tuple keys. Each of these tuples may have an associated `condition`.\nThe response returns a tree whose leaves are the specific users and usersets. Union, intersection and difference operator are located in the intermediate nodes.\n\n## Example\n\nTo expand all users that have the `reader` relationship with object `document:2021-budget`, use the Expand API with the following request body:\n```json\n{\n \"tuple_key\": {\n \"object\": \"document:2021-budget\",\n \"relation\": \"reader\"\n },\n \"authorization_model_id\": \"01G50QVV17PECNVAHX1GG4Y5NC\"\n}\n```\nOpenFGA's response is a userset tree of the users and usersets that have read access to the document.\n```json\n{\n \"tree\":{\n \"root\":{\n \"type\":\"document:2021-budget#reader\",\n \"union\":{\n \"nodes\":[\n {\n \"type\":\"document:2021-budget#reader\",\n \"leaf\":{\n \"users\":{\n \"users\":[\n \"user:bob\"\n ]\n }\n }\n },\n {\n \"type\":\"document:2021-budget#reader\",\n \"leaf\":{\n \"computed\":{\n \"userset\":\"document:2021-budget#writer\"\n }\n }\n }\n ]\n }\n }\n }\n}\n```\nThe caller can then call expand API for the `writer` relationship for the `document:2021-budget`.\n### Expand Request with Contextual Tuples\n\n\nGiven the model\n```python\nmodel\n schema 1.1\n\ntype user\n\ntype folder\n relations\n define owner: [user]\n\ntype document\n relations\n define parent: [folder]\n define viewer: [user] or writer\n define writer: [user] or owner from parent\n```\nand the initial tuples\n```json\n[{\n \"user\": \"user:bob\",\n \"relation\": \"owner\",\n \"object\": \"folder:1\"\n}]\n```\n\nTo expand all `writers` of `document:1` when `document:1` is put in `folder:1`, the first call could be:\n\n```json\n{\n \"tuple_key\": {\n \"object\": \"document:1\",\n \"relation\": \"writer\"\n },\n \"contextual_tuples\": {\n \"tuple_keys\": [\n {\n \"user\": \"folder:1\",\n \"relation\": \"parent\",\n \"object\": \"document:1\"\n }\n ]\n }\n}\n```\nthis returns:\n```json\n{\n \"tree\": {\n \"root\": {\n \"name\": \"document:1#writer\",\n \"union\": {\n \"nodes\": [\n {\n \"name\": \"document:1#writer\",\n \"leaf\": {\n \"users\": {\n \"users\": []\n }\n }\n },\n {\n \"name\": \"document:1#writer\",\n \"leaf\": {\n \"tupleToUserset\": {\n \"tupleset\": \"document:1#parent\",\n \"computed\": [\n {\n \"userset\": \"folder:1#owner\"\n }\n ]\n }\n }\n }\n ]\n }\n }\n }\n}\n```\nThis tells us that the `owner` of `folder:1` may also be a writer. So our next call could be to find the `owners` of `folder:1`\n```json\n{\n \"tuple_key\": {\n \"object\": \"folder:1\",\n \"relation\": \"owner\"\n }\n}\n```\nwhich gives\n```json\n{\n \"tree\": {\n \"root\": {\n \"name\": \"folder:1#owner\",\n \"leaf\": {\n \"users\": {\n \"users\": [\n \"user:bob\"\n ]\n }\n }\n }\n }\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/expand","href":"/api/service/relationship-queries/expand-relationships-in-userset-tree-format"},{"title":"List objects a user is related to","description":"The ListObjects API returns a list of all the objects of the given type that the user has a relation with.\n To arrive at a result, the API uses:\n\n- An [authorization model](/docs/getting-started/configure-model)\n- Explicit tuples written through the Write API\n- Contextual tuples present in the request\n- Implicit tuples that exist by virtue of applying set theory. For example:\n\n`document:2021-budget#viewer@document:2021-budget#viewer`\n\nIn the example the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`.\n\nAn `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID is used.\n\n> **Note:** We recommend you specify authorization model ID for better performance.\n\nYou may also specify `contextual_tuples` that is treated as regular tuples. Each of these tuples may have an associated `condition`.\nYou may also provide a `context` object that is used to evaluate the conditioned tuples in the system.\n\n> **Note:** We recommend you provide a value for all the input parameters of all the conditions, to ensure that all tuples be evaluated correctly.\n\nBy default, the Check API caches results for a short time to optimize performance. You may specify a value of `HIGHER_CONSISTENCY` for the optional `consistency` parameter in the body to inform the server that higher conisistency is preferred at the expense of increased latency. Consideration should be given to the increased latency if requesting higher consistency.\nThe response contains the related objects in an array in the \"objects\" field of the response and are strings in the object format `\u003ctype>:\u003cid>` (e.g. \"document:roadmap\").\n\nThe number of objects in the response array are limited by the execution timeout specified in the flag `OPENFGA_LIST_OBJECTS_DEADLINE` and by the upper bound specified in the flag `OPENFGA_LIST_OBJECTS_MAX_RESULTS`, whichever is hit first.\nThe objects given are not sorted, and therefore two identical calls can give a given different set of objects.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/list-objects","href":"/api/service/relationship-queries/list-objects-a-user-is-related-to"},{"title":"List all users with a relationship to an object","description":"The ListUsers API returns a list of all the users of a specific type that have a relation to a given object.\n\n To arrive at a result, the API uses:\n\n- An [authorization model](/docs/getting-started/configure-model)\n\n- Explicit tuples written through the Write API\n\n- Contextual tuples present in the request\n\n- Implicit tuples that exist by virtue of applying set theory\n\nFor example: `document:2021-budget#viewer@document:2021-budget#viewer`. In this example, the set of users who are viewers of `document:2021-budget` are the set of users who are the viewers of `document:2021-budget`.\n\nAn `authorization_model_id` may be specified in the body. If it is not specified, the latest authorization model ID is used.\n\n> **Note:** We recommend you specify authorization model ID for better performance.\n\nYou may also specify `contextual_tuples` that are treated as regular tuples. Each of these tuples may have an associated `condition`.\nYou may also provide a `context` object used to evaluate the conditioned tuples in the system.\n\n> **Note:** We recommend you provide a value for all the input parameters of all the conditions. This ensures that all tuples be evaluated correctly.\n\nThe response contains the related users in an array in the \"users\" field of the response. These results may include specific objects, usersets \nor type-bound public access. Each of these types of results is encoded in its own type and not represented as a string.\n\nIn cases where a type-bound public access result is returned (e.g. `user:*`), it cannot be inferred that all subjects\nof that type have a relation to the object; it is possible that negations exist and checks should still be queried\non individual subjects to ensure access to that document.\nThe number of users in the response array are limited by the execution timeout specified in the flag `OPENFGA_LIST_USERS_DEADLINE` and by the upper bound specified in the flag `OPENFGA_LIST_USERS_MAX_RESULTS`, whichever is hit first.\nThe returned users are not sorted, and therefore two identical calls may yield different sets of users.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/list-users","href":"/api/service/relationship-queries/list-all-users-with-a-relationship-to-an-object"},{"title":"Stream all objects with a user relationship","description":"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences: \n1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. \n2. The number of results returned is only limited by the execution timeout specified in the flag `OPENFGA_LIST_OBJECTS_DEADLINE`. \n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/streamed-list-objects","href":"/api/service/relationship-queries/stream-all-objects-with-a-user-relationship"}]},{"group":"Assertions","pages":[{"title":"Get assertions for a model","description":"The ReadAssertions API returns all the assertions stored for a given authorization model ID.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /stores/{store_id}/assertions/{authorization_model_id}","href":"/api/service/assertions/get-assertions-for-a-model"},{"title":"Upsert assertions for a model","description":"The WriteAssertions API upserts new assertions for an authorization model id, or overwrite the existing ones. An assertion is an object that contains a tuple key, the expectation of whether a call to the Check API of that tuple key returns true or false, and optionally a list of contextual tuples.","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json put /stores/{store_id}/assertions/{authorization_model_id}","href":"/api/service/assertions/upsert-assertions-for-a-model"}]},{"group":"AuthZenService","tag":"Experimental","pages":[{"title":"[Experimental] Get AuthZEN PDP configuration and capabilities","description":"[Experimental] The GetConfiguration API returns metadata about the Policy Decision Point (PDP) including its name, version, supported endpoints, and capabilities. This endpoint follows the AuthZEN specification for PDP discovery.\n\nFollowing the AuthZEN spec's multi-tenant pattern, OpenFGA provides a per-store discovery endpoint at `/.well-known/authzen-configuration/{store_id}`. This returns absolute endpoint URLs specific to that store.\n\n## Example Response\n```json\n{\n \"policy_decision_point\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV\",\n \"access_evaluation_endpoint\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV/access/v1/evaluation\",\n \"access_evaluations_endpoint\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV/access/v1/evaluations\",\n \"search_subject_endpoint\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV/access/v1/search/subject\",\n \"search_resource_endpoint\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV/access/v1/search/resource\",\n \"search_action_endpoint\": \"https://example.com/stores/01ARZ3NDEKTSV4RRFFQ69G5FAV/access/v1/search/action\"\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json get /.well-known/authzen-configuration/{store_id}","href":"/api/service/authzenservice/[experimental]-get-authzen-pdp-configuration-and-capabilities"},{"title":"[Experimental] Evaluate whether a subject can perform an action on a resource","description":"[Experimental] The Evaluation API determines whether a subject is authorized to perform an action on a resource. This endpoint implements the AuthZEN Access Evaluation API specification.\n\n## Request Structure\nThe request requires three components:\n- **subject**: The entity requesting access (e.g., a user or service)\n- **action**: The operation being performed (maps to a relation in the authorization model)\n- **resource**: The object being accessed\n\nEach component has a `type` and `id` field, and may include optional `properties` for ABAC (Attribute-Based Access Control) conditions.\n\n## Response\nThe response contains a `decision` field (boolean) indicating whether access is permitted, and an optional `context` object with additional information such as the evaluation ID or error details.\n\n## ABAC Support\nProperties on subject, action, and resource are automatically merged into the evaluation context with prefixes:\n- Subject properties: `subject_\u003cproperty_name>`\n- Resource properties: `resource_\u003cproperty_name>`\n- Action properties: `action_\u003cproperty_name>`\n\nThese merged properties can be used in conditions defined in your authorization model.\n\n## Examples\n### Basic authorization check\nCheck if user Anne can read a document:\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"action\": {\"name\": \"can_read\"},\n \"resource\": {\"type\": \"document\", \"id\": \"roadmap\"}\n}\n```\nResponse when authorized:\n```json\n{\n \"decision\": true\n}\n```\n### Using properties for ABAC\nCheck access with subject and resource attributes:\n```json\n{\n \"subject\": {\n \"type\": \"user\",\n \"id\": \"anne\",\n \"properties\": {\"department\": \"engineering\", \"clearance_level\": 3}\n },\n \"action\": {\"name\": \"can_read\"},\n \"resource\": {\n \"type\": \"document\",\n \"id\": \"secret-project\",\n \"properties\": {\"classification\": \"confidential\", \"required_clearance\": 2}\n }\n}\n```\n### Using request context\nProvide additional context for time-based or environmental conditions:\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"bob\"},\n \"action\": {\"name\": \"can_access\"},\n \"resource\": {\"type\": \"system\", \"id\": \"production\"},\n \"context\": {\n \"current_time\": \"2024-01-15T14:30:00Z\",\n \"ip_address\": \"192.168.1.100\",\n \"is_vpn_connected\": true\n }\n}\n```\n### Specifying authorization model\nPin the evaluation to a specific authorization model version using the `Openfga-Authorization-Model-Id` header:\n```\nPOST /stores/{store_id}/access/v1/evaluation\nOpenfga-Authorization-Model-Id: 01G50QVV17PECNVAHX1GG4Y5NC\n\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"action\": {\"name\": \"can_write\"},\n \"resource\": {\"type\": \"document\", \"id\": \"budget-2024\"}\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/access/v1/evaluation","href":"/api/service/authzenservice/[experimental]-evaluate-whether-a-subject-can-perform-an-action-on-a-resource"},{"title":"[Experimental] Check whether one or more users are authorized to access resources","description":"[Experimental] The Evaluations API allows batch authorization checks in a single request. It supports request-level defaults for subject, action, resource, and context that can be overridden per evaluation item.\n\n## Evaluation Semantics\nThe `options.evaluations_semantic` field controls how evaluations are processed:\n- `execute_all` (default): Execute all evaluations and return all results\n- `deny_on_first_deny`: Stop processing on first deny decision\n- `permit_on_first_permit`: Stop processing on first permit decision\n\nWhen using `deny_on_first_deny` or `permit_on_first_permit`, the response may include fewer items than the request because processing short-circuits when the condition is met.\n\n## Authorization Model Selection\nTo pin evaluations to a specific authorization model version, send the `Openfga-Authorization-Model-Id` header. If the header is not provided, the latest model is used.\n\n## Examples\n### Basic batch evaluation\nCheck if a user can perform multiple actions on a document:\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"resource\": {\"type\": \"document\", \"id\": \"roadmap\"},\n \"evaluations\": [\n {\"action\": {\"name\": \"can_read\"}},\n {\"action\": {\"name\": \"can_write\"}},\n {\"action\": {\"name\": \"can_delete\"}}\n ]\n}\n```\n### Using evaluation semantics\nStop on first permitted action (useful for finding any valid permission):\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"resource\": {\"type\": \"document\", \"id\": \"roadmap\"},\n \"evaluations\": [\n {\"action\": {\"name\": \"can_read\"}},\n {\"action\": {\"name\": \"can_write\"}}\n ],\n \"options\": {\n \"evaluations_semantic\": \"permit_on_first_permit\"\n }\n}\n```\n### Overriding defaults per evaluation\nCheck permissions across multiple resources:\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"action\": {\"name\": \"can_read\"},\n \"evaluations\": [\n {\"resource\": {\"type\": \"document\", \"id\": \"doc1\"}},\n {\"resource\": {\"type\": \"document\", \"id\": \"doc2\"}},\n {\"resource\": {\"type\": \"folder\", \"id\": \"folder1\"}}\n ]\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/access/v1/evaluations","href":"/api/service/authzenservice/[experimental]-check-whether-one-or-more-users-are-authorized-to-access-resources"},{"title":"[Experimental] Search for actions a subject can perform on a resource","description":"[Experimental] The ActionSearch API returns all actions (relations) that a subject can perform on a specific resource. This is useful for answering questions like \"What can Anne do with this document?\" or building dynamic UIs that show only the actions a user is permitted to perform.\n\n## Examples\n### Find all actions a user can perform on a document\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"resource\": {\"type\": \"document\", \"id\": \"roadmap\"}\n}\n```\nResponse:\n```json\n{\n \"results\": [\n {\"name\": \"can_read\"},\n {\"name\": \"can_write\"},\n {\"name\": \"can_share\"}\n ],\n \"page\": {\"count\": 3}\n}\n```\n### Search with ABAC context for time-based permissions\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"bob\"},\n \"resource\": {\"type\": \"report\", \"id\": \"quarterly-financials\"},\n \"context\": {\n \"current_time\": \"2024-01-15T14:30:00Z\",\n \"user_department\": \"finance\"\n }\n}\n```\n### Paginated action search\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"admin\"},\n \"resource\": {\"type\": \"system\", \"id\": \"production\"},\n \"page\": {\"limit\": 50}\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/access/v1/search/action","href":"/api/service/authzenservice/[experimental]-search-for-actions-a-subject-can-perform-on-a-resource"},{"title":"[Experimental] Search for resources a subject has access to","description":"[Experimental] The ResourceSearch API returns all resources of a given type that a subject has a specific action (relation) on. This is useful for answering questions like \"What documents can Anne read?\" or \"What folders can Bob administer?\"\n\nThe resource type filter is required. Results support pagination for large result sets.\n\n## Examples\n### Find all documents a user can read\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"action\": {\"name\": \"can_read\"},\n \"resource\": {\"type\": \"document\"}\n}\n```\nResponse:\n```json\n{\n \"results\": [\n {\"type\": \"document\", \"id\": \"roadmap\"},\n {\"type\": \"document\", \"id\": \"budget-2024\"},\n {\"type\": \"document\", \"id\": \"team-roster\"}\n ],\n \"page\": {\"count\": 3}\n}\n```\n### Find folders a user can administer with pagination\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"bob\"},\n \"action\": {\"name\": \"can_admin\"},\n \"resource\": {\"type\": \"folder\"},\n \"page\": {\"limit\": 25}\n}\n```\n### Search with ABAC context\n```json\n{\n \"subject\": {\"type\": \"user\", \"id\": \"anne\"},\n \"action\": {\"name\": \"can_read\"},\n \"resource\": {\"type\": \"document\"},\n \"context\": {\n \"current_time\": \"2024-01-15T10:00:00Z\",\n \"ip_address\": \"192.168.1.100\"\n }\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/access/v1/search/resource","href":"/api/service/authzenservice/[experimental]-search-for-resources-a-subject-has-access-to"},{"title":"[Experimental] Search for subjects with access to a resource","description":"[Experimental] The SubjectSearch API returns all subjects that have a specific action (relation) on a given resource. This is useful for answering questions like \"Who can read this document?\" or \"Who can administer this folder?\"\n\nResults can be filtered by subject type and support pagination for large result sets.\n\n## Examples\n### Find all users who can read a document\n```json\n{\n \"resource\": {\"type\": \"document\", \"id\": \"roadmap\"},\n \"action\": {\"name\": \"can_read\"},\n \"subject\": {\"type\": \"user\"}\n}\n```\nResponse:\n```json\n{\n \"results\": [\n {\"type\": \"user\", \"id\": \"anne\"},\n {\"type\": \"user\", \"id\": \"bob\"},\n {\"type\": \"user\", \"id\": \"charlie\"}\n ],\n \"page\": {\"count\": 3}\n}\n```\n### Paginated search with limit\n```json\n{\n \"resource\": {\"type\": \"folder\", \"id\": \"engineering\"},\n \"action\": {\"name\": \"can_view\"},\n \"subject\": {\"type\": \"user\"},\n \"page\": {\"limit\": 10}\n}\n```\n### Continue from previous page\n```json\n{\n \"resource\": {\"type\": \"folder\", \"id\": \"engineering\"},\n \"action\": {\"name\": \"can_view\"},\n \"subject\": {\"type\": \"user\"},\n \"page\": {\"token\": \"eyJsYXN0X2lkIjoiMTAwIn0=\", \"limit\": 10}\n}\n```\n","deprecated":null,"version":null,"openapi":"https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/access/v1/search/subject","href":"/api/service/authzenservice/[experimental]-search-for-subjects-with-access-to-a-resource"}]}]}]},"title":"Get stored relationship tuples - OpenFGA","buildId":"dpl_GvhK4qVXq51DpfYJLCtPpYNN4YHN","deploymentId":"dpl_GvhK4qVXq51DpfYJLCtPpYNN4YHN","dynamics":["c2aa737661","b0f84f53ff","a9bb46feb3","2b790eda92"],"chunks":["OpenApiReferenceProvider-Bg4Z7D_G.js","utils-Biz734EK.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-C6F9YHs6.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BoJjY_VP.js","snippetPresets-CnZ-mOFh.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","Page-BeiUfucV.js","ApiExamples-DC_SB2pp.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BYKtOiIP.js","shallow-COAac_UD.js","getApiPlaygroundDisplay-BV4Viqi2.js","CodeSnippet-DDgW-JXl.js","CodeSnippets-CP1LpNhG.js","getPastedJson-Cvgvbfmv.js","icon-D-H368xH.js","MethodPill-CXSxH1VW.js","DuplicateIcon-JcbBzF1x.js","createIcon-BDt_aHZM.js","DynamicMarkdown-DO1Fz7ar.js","SectionHeading-mwKBArs3.js","axios-vUo_bRtp.js","Markdown-C3KUTGJN.js","clsx-C6CAjViH.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-C3vb5JQZ.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-C8Hisf3g.js"]}