The Streamed ListObjects API is very similar to the the ListObjects API, with two differences:
Instead of collecting all objects before returning a response, it streams them to the client as they are collected.
The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.
POST
/
stores
/
{store_id}
/
streamed-list-objects
Node.js
const { OpenFgaClient, ConsistencyPreference } = require('@openfga/sdk');
const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Set to the authorization model ID for this request.
});
async function main() {
const body = {
"user": "user:anne",
"relation": "reader",
"type": "document"
};
for await (const item of fgaClient.streamedListObjects(body)) {
console.log(item.object);
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
package main
import (
"context"
"os"
"fmt"
. "github.com/openfga/go-sdk/client"
)
func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiUrl: os.Getenv("FGA_API_URL"),
StoreId: os.Getenv("FGA_STORE_ID"),
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // Set to the authorization model ID for this request.
})
if err != nil {
panic(err)
}
body := ClientStreamedListObjectsRequest{
User: "user:anne",
Relation: "reader",
Type: "document",
}
stream, err := fgaClient.StreamedListObjects(context.Background()).Body(body).Execute()
if err != nil {
panic(err)
}
defer stream.Close()
for item := range stream.Objects {
fmt.Println(item.Object)
}
if err := <-stream.Errors; err != nil {
panic(err)
}
}
using System.Collections.Generic;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Client.Model;
using OpenFga.Sdk.Model;
using Environment = System.Environment;
using System;
var fgaClient = new OpenFgaClient(new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"),
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"),
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Set to the authorization model ID for this request.
});
var body = new ClientListObjectsRequest {
User = "user:anne",
Relation = "reader",
Type = "document",
};
await foreach (var item in fgaClient.StreamedListObjects(body)) {
Console.WriteLine(item.Object);
}
import asyncio
import os
from openfga_sdk.client import OpenFgaClient, ClientConfiguration
from openfga_sdk.client.models import ClientListObjectsRequest
async def main():
configuration = ClientConfiguration(
api_url=os.environ.get("FGA_API_URL"),
store_id=os.environ.get("FGA_STORE_ID"),
authorization_model_id=os.environ.get("FGA_MODEL_ID"), # Set to the authorization model ID for this request.
)
async with OpenFgaClient(configuration) as fga_client:
body = ClientListObjectsRequest(
user="user:anne",
relation="reader",
type="document",
)
async for item in fga_client.streamed_list_objects(body=body):
print(item.object)
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;
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"))
.authorizationModelId(System.getenv("FGA_MODEL_ID")); // Set to the authorization model ID for this request.
var fgaClient = new OpenFgaClient(config);
var body = new ClientListObjectsRequest()
.user("user:anne")
.relation("reader")
.type("document");
fgaClient.streamedListObjects(body, item -> System.out.println(item.getObject())).get();
}
}
# Set FGA_API_URL to the URL of your OpenFGA server.
# Set FGA_STORE_ID to your store ID.
# Set FGA_MODEL_ID to your authorization model ID.
# These examples use a server with authentication disabled.
# For authenticated servers, see /docs/getting-started/setup-sdk-client.
curl --no-buffer -X POST "$FGA_API_URL/stores/$FGA_STORE_ID/streamed-list-objects" \
-H "content-type: application/json" \
-d '{
"authorization_model_id": "'"$FGA_MODEL_ID"'",
"user": "user:anne",
"relation": "reader",
"type": "document"
}'
const { OpenFgaClient, ConsistencyPreference } = require('@openfga/sdk');
const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL,
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Set to the authorization model ID for this request.
});
async function main() {
const body = {
"user": "user:anne",
"relation": "reader",
"type": "document"
};
for await (const item of fgaClient.streamedListObjects(body)) {
console.log(item.object);
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
package main
import (
"context"
"os"
"fmt"
. "github.com/openfga/go-sdk/client"
)
func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiUrl: os.Getenv("FGA_API_URL"),
StoreId: os.Getenv("FGA_STORE_ID"),
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // Set to the authorization model ID for this request.
})
if err != nil {
panic(err)
}
body := ClientStreamedListObjectsRequest{
User: "user:anne",
Relation: "reader",
Type: "document",
}
stream, err := fgaClient.StreamedListObjects(context.Background()).Body(body).Execute()
if err != nil {
panic(err)
}
defer stream.Close()
for item := range stream.Objects {
fmt.Println(item.Object)
}
if err := <-stream.Errors; err != nil {
panic(err)
}
}
using System.Collections.Generic;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Client.Model;
using OpenFga.Sdk.Model;
using Environment = System.Environment;
using System;
var fgaClient = new OpenFgaClient(new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"),
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"),
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Set to the authorization model ID for this request.
});
var body = new ClientListObjectsRequest {
User = "user:anne",
Relation = "reader",
Type = "document",
};
await foreach (var item in fgaClient.StreamedListObjects(body)) {
Console.WriteLine(item.Object);
}
import asyncio
import os
from openfga_sdk.client import OpenFgaClient, ClientConfiguration
from openfga_sdk.client.models import ClientListObjectsRequest
async def main():
configuration = ClientConfiguration(
api_url=os.environ.get("FGA_API_URL"),
store_id=os.environ.get("FGA_STORE_ID"),
authorization_model_id=os.environ.get("FGA_MODEL_ID"), # Set to the authorization model ID for this request.
)
async with OpenFgaClient(configuration) as fga_client:
body = ClientListObjectsRequest(
user="user:anne",
relation="reader",
type="document",
)
async for item in fga_client.streamed_list_objects(body=body):
print(item.object)
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;
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"))
.authorizationModelId(System.getenv("FGA_MODEL_ID")); // Set to the authorization model ID for this request.
var fgaClient = new OpenFgaClient(config);
var body = new ClientListObjectsRequest()
.user("user:anne")
.relation("reader")
.type("document");
fgaClient.streamedListObjects(body, item -> System.out.println(item.getObject())).get();
}
}
# Set FGA_API_URL to the URL of your OpenFGA server.
# Set FGA_STORE_ID to your store ID.
# Set FGA_MODEL_ID to your authorization model ID.
# These examples use a server with authentication disabled.
# For authenticated servers, see /docs/getting-started/setup-sdk-client.
curl --no-buffer -X POST "$FGA_API_URL/stores/$FGA_STORE_ID/streamed-list-objects" \
-H "content-type: application/json" \
-d '{
"authorization_model_id": "'"$FGA_MODEL_ID"'",
"user": "user:anne",
"relation": "reader",
"type": "document"
}'
{
"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":[],"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-queries/stream-all-objects-with-a-user-relationship","slug":"/api/service/relationship-queries/stream-all-objects-with-a-user-relationship","pageMetadata":{"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","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 li: \"li\",\n ol: \"ol\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences:\"\n }), \"\\n\", _jsxs(_components.ol, {\n children: [\"\\n\", _jsx(_components.li, {\n children: \"Instead of collecting all objects before returning a response, it streams them to the client as they are collected.\"\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"The number of results returned is only limited by the execution timeout specified in the flag \", _jsx(_components.code, {\n children: \"OPENFGA_LIST_OBJECTS_DEADLINE\"\n }), \".\"]\n }), \"\\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};\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":"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","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 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","operationId":"StreamedListObjects","parameters":["5d171789-fce2-4d18-af14-3f03580f593e"],"requestBody":"6a62b78c-04ba-491c-aa8a-dec4aecaa5cf","responses":{"200":"20512087-17fa-4541-b860-69f7c93dec3e","400":"3f9075ec-2274-4d82-abf2-8c91e9ef20d0","401":"6d467be6-b474-4882-8d83-7bce47a77b4a","403":"164b1068-5b3c-4a11-9ddf-26f095e66662","404":"e931b99a-e315-4877-92d9-7ee6dff27e27","409":"db124526-3053-4c22-959c-5b1ce3dc87fb","422":"2f3976af-c84c-4f43-81f8-664c4c5d4dbd","500":"1271fe7e-fd63-4e12-b105-f7c57ee79a19"},"summary":"Stream all objects with a user relationship","tags":["Relationship Queries"],"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 authorizationModelId: process.env.FGA_MODEL_ID, // Set to the authorization model ID for this request.\n});\n\nasync function main() {\n const body = {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"type\": \"document\"\n };\n for await (const item of fgaClient.streamedListObjects(body)) {\n console.log(item.object);\n }\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 \"fmt\"\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 AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Set to the authorization model ID for this request.\n })\n if err != nil {\n panic(err)\n }\n \n body := ClientStreamedListObjectsRequest{\n User: \"user:anne\",\n Relation: \"reader\",\n Type: \"document\",\n }\n stream, err := fgaClient.StreamedListObjects(context.Background()).Body(body).Execute()\n if err != nil {\n panic(err)\n }\n defer stream.Close()\n for item := range stream.Objects {\n fmt.Println(item.Object)\n }\n if err := \u003c-stream.Errors; err != nil {\n panic(err)\n }\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;\nusing System;\n\nvar fgaClient = new OpenFgaClient(new ClientConfiguration() {\n ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"),\n StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"),\n AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // Set to the authorization model ID for this request.\n});\n\nvar body = new ClientListObjectsRequest {\n User = \"user:anne\",\n Relation = \"reader\",\n Type = \"document\",\n};\nawait foreach (var item in fgaClient.StreamedListObjects(body)) {\n Console.WriteLine(item.Object);\n}"},{"lang":"python","label":"Python","source":"import asyncio\nimport os\nfrom openfga_sdk.client import OpenFgaClient, ClientConfiguration\nfrom openfga_sdk.client.models import ClientListObjectsRequest\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 authorization_model_id=os.environ.get(\"FGA_MODEL_ID\"), # Set to the authorization model ID for this request.\n )\n async with OpenFgaClient(configuration) as fga_client:\n body = ClientListObjectsRequest(\n user=\"user:anne\",\n relation=\"reader\",\n type=\"document\",\n )\n async for item in fga_client.streamed_list_objects(body=body):\n print(item.object)\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;\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 .authorizationModelId(System.getenv(\"FGA_MODEL_ID\")); // Set to the authorization model ID for this request.\n var fgaClient = new OpenFgaClient(config);\n \n var body = new ClientListObjectsRequest()\n .user(\"user:anne\")\n .relation(\"reader\")\n .type(\"document\");\n fgaClient.streamedListObjects(body, item -> System.out.println(item.getObject())).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# Set FGA_MODEL_ID to your authorization model ID.\n# These examples use a server with authentication disabled.\n# For authenticated servers, see /docs/getting-started/setup-sdk-client.\n\ncurl --no-buffer -X POST \"$FGA_API_URL/stores/$FGA_STORE_ID/streamed-list-objects\" \\\n -H \"content-type: application/json\" \\\n -d '{\n \"authorization_model_id\": \"'\"$FGA_MODEL_ID\"'\",\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"type\": \"document\"\n}'"}],"method":"post","type":"path","servers":[],"security":[],"path":"/stores/{store_id}/streamed-list-objects","baseUrlOptions":[],"title":"Stream all objects with a user relationship","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 authorizationModelId: process.env.FGA_MODEL_ID, // Set to the authorization model ID for this request.\n});\n\nasync function main() {\n const body = {\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"type\": \"document\"\n };\n for await (const item of fgaClient.streamedListObjects(body)) {\n console.log(item.object);\n }\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 \"fmt\"\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 AuthorizationModelId: os.Getenv(\"FGA_MODEL_ID\"), // Set to the authorization model ID for this request.\n })\n if err != nil {\n panic(err)\n }\n \n body := ClientStreamedListObjectsRequest{\n User: \"user:anne\",\n Relation: \"reader\",\n Type: \"document\",\n }\n stream, err := fgaClient.StreamedListObjects(context.Background()).Body(body).Execute()\n if err != nil {\n panic(err)\n }\n defer stream.Close()\n for item := range stream.Objects {\n fmt.Println(item.Object)\n }\n if err := \u003c-stream.Errors; err != nil {\n panic(err)\n }\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;\nusing System;\n\nvar fgaClient = new OpenFgaClient(new ClientConfiguration() {\n ApiUrl = Environment.GetEnvironmentVariable(\"FGA_API_URL\"),\n StoreId = Environment.GetEnvironmentVariable(\"FGA_STORE_ID\"),\n AuthorizationModelId = Environment.GetEnvironmentVariable(\"FGA_MODEL_ID\"), // Set to the authorization model ID for this request.\n});\n\nvar body = new ClientListObjectsRequest {\n User = \"user:anne\",\n Relation = \"reader\",\n Type = \"document\",\n};\nawait foreach (var item in fgaClient.StreamedListObjects(body)) {\n Console.WriteLine(item.Object);\n}"},{"label":"Python","lang":"python","source":"import asyncio\nimport os\nfrom openfga_sdk.client import OpenFgaClient, ClientConfiguration\nfrom openfga_sdk.client.models import ClientListObjectsRequest\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 authorization_model_id=os.environ.get(\"FGA_MODEL_ID\"), # Set to the authorization model ID for this request.\n )\n async with OpenFgaClient(configuration) as fga_client:\n body = ClientListObjectsRequest(\n user=\"user:anne\",\n relation=\"reader\",\n type=\"document\",\n )\n async for item in fga_client.streamed_list_objects(body=body):\n print(item.object)\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;\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 .authorizationModelId(System.getenv(\"FGA_MODEL_ID\")); // Set to the authorization model ID for this request.\n var fgaClient = new OpenFgaClient(config);\n \n var body = new ClientListObjectsRequest()\n .user(\"user:anne\")\n .relation(\"reader\")\n .type(\"document\");\n fgaClient.streamedListObjects(body, item -> System.out.println(item.getObject())).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# Set FGA_MODEL_ID to your authorization model ID.\n# These examples use a server with authentication disabled.\n# For authenticated servers, see /docs/getting-started/setup-sdk-client.\n\ncurl --no-buffer -X POST \"$FGA_API_URL/stores/$FGA_STORE_ID/streamed-list-objects\" \\\n -H \"content-type: application/json\" \\\n -d '{\n \"authorization_model_id\": \"'\"$FGA_MODEL_ID\"'\",\n \"user\": \"user:anne\",\n \"relation\": \"reader\",\n \"type\": \"document\"\n}'"}],"requiredOnlyExamples":false,"requestExampleType":"codeSamples","responseExampleType":"generated"},"dependencies":{"parameters":{"5d171789-fce2-4d18-af14-3f03580f593e":{"in":"path","name":"store_id","required":true,"schema":{"type":"string","isRequired":true,"uniqueKey":"","typeLabel":"string"}}},"requestBody":{"content":{"application/json":{"schema":{"properties":{"relation":{"example":"reader","type":"string","isRequired":true,"uniqueKey":"relation","typeLabel":"string"},"type":{"example":"document","type":"string","isRequired":true,"uniqueKey":"type","typeLabel":"string"},"user":{"example":"user:anne","maxLength":512,"minLength":1,"type":"string","isRequired":true,"uniqueKey":"user","typeLabel":"string"},"authorization_model_id":{"example":"01G5JAVJ41T49E9TT3SKVS7X1J","type":"string","uniqueKey":"authorization_model_id","typeLabel":"string"},"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>"},"context":{"description":"Additional request context used to evaluate any ABAC conditions encountered\nin the query evaluation.","type":"object","uniqueKey":"context","typeLabel":"object"},"contextual_tuples":{"properties":{"tuple_keys":{"items":{"type":"object","required":["user","relation","object"],"properties":{"object":{"example":"document:2021-budget","maxLength":256,"type":"string","isRequired":true,"uniqueKey":"contextual_tuples.tuple_keys.items.[INDEX].object","typeLabel":"string"},"relation":{"example":"reader","maxLength":50,"type":"string","isRequired":true,"uniqueKey":"contextual_tuples.tuple_keys.items.[INDEX].relation","typeLabel":"string"},"user":{"example":"user:anne","maxLength":512,"type":"string","isRequired":true,"uniqueKey":"contextual_tuples.tuple_keys.items.[INDEX].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":"contextual_tuples.tuple_keys.items.[INDEX].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":"contextual_tuples.tuple_keys.items.[INDEX].condition.context","typeLabel":"object"}},"required":["name"],"type":"object","uniqueKey":"contextual_tuples.tuple_keys.items.[INDEX].condition","typeLabel":"object"}},"uniqueKey":"contextual_tuples.tuple_keys.items.[INDEX]","typeLabel":"object"},"maxItems":100,"type":"array","isRequired":true,"uniqueKey":"contextual_tuples.tuple_keys","typeLabel":"object[]"}},"required":["tuple_keys"],"type":"object","uniqueKey":"contextual_tuples","typeLabel":"object"}},"required":["type","relation","user"],"type":"object","uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"relation":"reader","type":"document","user":"user:anne","authorization_model_id":"01G5JAVJ41T49E9TT3SKVS7X1J","consistency":"MINIMIZE_LATENCY","context":{}}}},"exampleType":"generated"}},"required":true,"exampleType":"generated"},"responses":{"20512087-17fa-4541-b860-69f7c93dec3e":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"format":"int32","type":"integer","uniqueKey":"error.code","typeLabel":"integer\u003cint32>"},"details":{"items":{"type":"object","properties":{"@type":{"type":"string","uniqueKey":"error.details.items.[INDEX].@type","typeLabel":"string"}},"additionalProperties":{"oneOf":[{}],"uniqueKey":"error.details.items.[INDEX].additionalProperties","typeLabel":"any"},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"type":"array","uniqueKey":"error.details","typeLabel":"object[]"},"message":{"type":"string","uniqueKey":"error.message","typeLabel":"string"}},"type":"object","uniqueKey":"error","typeLabel":"object"},"result":{"description":"The response for a StreamedListObjects RPC.","properties":{"object":{"example":"document:roadmap","type":"string","isRequired":true,"uniqueKey":"result.object","typeLabel":"string"}},"required":["object"],"type":"object","uniqueKey":"result","typeLabel":"object"}},"title":"Stream result of StreamedListObjectsResponse","type":"object","uniqueKey":"","typeLabel":"Stream result of StreamedListObjectsResponse ยท object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":123,"details":[{"@type":"\u003cstring>"}],"message":"\u003cstring>"},"result":{"object":"document:roadmap"}}}},"exampleType":"generated"}},"description":"A successful response.(streaming responses)","exampleType":"generated"},"3f9075ec-2274-4d82-abf2-8c91e9ef20d0":{"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"},"6d467be6-b474-4882-8d83-7bce47a77b4a":{"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"},"164b1068-5b3c-4a11-9ddf-26f095e66662":{"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"},"e931b99a-e315-4877-92d9-7ee6dff27e27":{"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"},"db124526-3053-4c22-959c-5b1ce3dc87fb":{"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"},"2f3976af-c84c-4f43-81f8-664c4c5d4dbd":{"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"},"1271fe7e-fd63-4e12-b105-f7c57ee79a19":{"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":"Stream all objects with a user relationship - OpenFGA","relatedPagesConfig":{"enabled":false,"limit":5,"mode":"automatic"},"navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-28T07:36:44.256Z","originalFileLocation":"api/service/relationship-queries/stream-all-objects-with-a-user-relationship.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 Streamed ListObjects API is very similar to the the ListObjects API, with two differences: 1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. 2. The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.\">\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=\"Stream all objects with a user relationship - OpenFGA\">\u003cmeta data-mint-head property=\"og:description\" content=\"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences: 1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. 2. The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.\">\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-queries/stream-all-objects-with-a-user-relationship\">\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=\"Stream all objects with a user relationship - OpenFGA\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences: 1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. 2. The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.\">\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-queries/stream-all-objects-with-a-user-relationship\">\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-queries/stream-all-objects-with-a-user-relationship.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-queries/stream-all-objects-with-a-user-relationship#webpage\",\"url\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship\",\"name\":\"Stream all objects with a user relationship\",\"description\":\"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences: 1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. 2. The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.\",\"dateModified\":\"2026-09-28T07:36:44.256Z\",\"isPartOf\":{\"@id\":\"https://openfga.dev/docs#website\"},\"breadcrumb\":{\"@id\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Relationship Queries\",\"item\":\"https://openfga.dev/docs/api/service/relationship-queries/check-multiple-authorizations-in-a-single-request\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Stream all objects with a user relationship\",\"item\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship#apireference\",\"headline\":\"Stream all objects with a user relationship\",\"name\":\"Stream all objects with a user relationship\",\"description\":\"The Streamed ListObjects API is very similar to the the ListObjects API, with two differences: 1. Instead of collecting all objects before returning a response, it streams them to the client as they are collected. 2. The number of results returned is only limited by the execution timeout specified in the flag OPENFGA_LIST_OBJECTS_DEADLINE.\",\"url\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship\",\"mainEntityOfPage\":{\"@id\":\"https://openfga.dev/docs/api/service/relationship-queries/stream-all-objects-with-a-user-relationship#webpage\"},\"image\":\"https://openfga.dev/img/og-rich-embed.png\",\"dateModified\":\"2026-09-28T07:36:44.256Z\",\"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","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"},{"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","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":"Stream all objects with a user relationship - 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"]}