> ## Documentation Index
> Fetch the complete documentation index at: https://openfga.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a new authorization model

> The WriteAuthorizationModel API adds a new authorization model to a store.
Each item in the `type_definitions` array is a type definition as specified in the field `type_definition`.
The response returns the authorization model's ID in the `id` field.

## Example

To add an authorization model with `user` and `document` type definitions, call `POST` `authorization-models` API with the body: 
```json
{
  "type_definitions":[
    {
      "type":"user"
    },
    {
      "type":"document",
      "relations":{
        "reader":{
          "union":{
            "child":[
              {
                "this":{}
              },
              {
                "computedUserset":{
                  "object":"",
                  "relation":"writer"
                }
              }
            ]
          }
        },
        "writer":{
          "this":{}
        }
      }
    }
  ]
}
```
OpenFGA's response includes the version id for this authorization model, similar to:
```
{"authorization_model_id": "01G50QVV17PECNVAHX1GG4Y5NC"}
```




## OpenAPI

````yaml https://raw.githubusercontent.com/openfga/api/refs/heads/main/docs/openapiv3/apidocs.openapi.json post /stores/{store_id}/authorization-models
openapi: 3.0.3
info:
  contact:
    email: community@openfga.dev
    name: OpenFGA
    url: https://openfga.dev
  description: >-
    A high performance and flexible authorization/permission engine built for
    developers and inspired by Google Zanzibar.
  license:
    name: Apache-2.0
    url: https://github.com/openfga/openfga/blob/main/LICENSE
  title: OpenFGA
  version: 1.x
servers: []
security: []
tags:
  - name: AuthZenService
  - name: OpenFGAService
paths:
  /stores/{store_id}/authorization-models:
    post:
      tags:
        - Authorization Models
      summary: Create a new authorization model
      description: >
        The WriteAuthorizationModel API adds a new authorization model to a
        store.

        Each item in the `type_definitions` array is a type definition as
        specified in the field `type_definition`.

        The response returns the authorization model's ID in the `id` field.


        ## Example


        To add an authorization model with `user` and `document` type
        definitions, call `POST` `authorization-models` API with the body: 

        ```json

        {
          "type_definitions":[
            {
              "type":"user"
            },
            {
              "type":"document",
              "relations":{
                "reader":{
                  "union":{
                    "child":[
                      {
                        "this":{}
                      },
                      {
                        "computedUserset":{
                          "object":"",
                          "relation":"writer"
                        }
                      }
                    ]
                  }
                },
                "writer":{
                  "this":{}
                }
              }
            }
          ]
        }

        ```

        OpenFGA's response includes the version id for this authorization model,
        similar to:

        ```

        {"authorization_model_id": "01G50QVV17PECNVAHX1GG4Y5NC"}

        ```
      operationId: WriteAuthorizationModel
      parameters:
        - in: path
          name: store_id
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WriteAuthorizationModelBody'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WriteAuthorizationModelResponse'
          description: A successful response.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorMessageResponse'
          description: Request failed due to invalid input.
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthenticatedResponse'
          description: Not authenticated.
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
          description: Forbidden.
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PathUnknownErrorMessageResponse'
          description: Request failed due to incorrect path.
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AbortedMessageResponse'
          description: Request was aborted due a transaction conflict.
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableContentMessageResponse'
          description: Request timed out due to excessive request throttling.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorMessageResponse'
          description: Request failed due to internal server error.
      x-codeSamples:
        - lang: node
          label: Node.js
          source: >-
            const { OpenFgaClient, ConsistencyPreference } =
            require('@openfga/sdk');


            const fgaClient = new OpenFgaClient({
              apiUrl: process.env.FGA_API_URL,
              storeId: process.env.FGA_STORE_ID,
            });


            async function main() {
                const body = {
                  "schema_version": "1.1",
                  "type_definitions": [
                    {
                      "type": "user"
                    },
                    {
                      "type": "document",
                      "relations": {
                        "reader": {
                          "this": {}
                        }
                      },
                      "metadata": {
                        "relations": {
                          "reader": {
                            "directly_related_user_types": [
                              {
                                "type": "user"
                              }
                            ]
                          }
                        }
                      }
                    }
                  ]
                };
                const response = await fgaClient.writeAuthorizationModel(body);
            }


            main().catch((error) => {
                console.error(error);
                process.exitCode = 1;
            });
        - lang: go
          label: Go
          source: |-
            package main

            import (
                "context"
                "os"
                "encoding/json"
                . "github.com/openfga/go-sdk/client"
            )

            func main() {
                fgaClient, err := NewSdkClient(&ClientConfiguration{
                    ApiUrl: os.Getenv("FGA_API_URL"),
                    StoreId: os.Getenv("FGA_STORE_ID"),
                })
                if err != nil {
                    panic(err)
                }
                
                modelJSON := `{
                  "schema_version": "1.1",
                  "type_definitions": [
                    {
                      "type": "user"
                    },
                    {
                      "type": "document",
                      "relations": {
                        "reader": {
                          "this": {}
                        }
                      },
                      "metadata": {
                        "relations": {
                          "reader": {
                            "directly_related_user_types": [
                              {
                                "type": "user"
                              }
                            ]
                          }
                        }
                      }
                    }
                  ]
                }`
                var body ClientWriteAuthorizationModelRequest
                if err := json.Unmarshal([]byte(modelJSON), &body); err != nil {
                    panic(err)
                }
                response, err := fgaClient.WriteAuthorizationModel(context.Background()).Body(body).Execute()
                if err != nil {
                    panic(err)
                }
                _ = response
            }
        - lang: dotnet
          label: .NET
          source: >-
            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"),
            });


            var body =
            ClientWriteAuthorizationModelRequest.FromJson("{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"user\"},{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}")
                ?? throw new InvalidOperationException("Failed to deserialize the authorization model.");
            var response = await fgaClient.WriteAuthorizationModel(body);
        - lang: python
          label: Python
          source: >-
            import asyncio

            import os

            from openfga_sdk.client import OpenFgaClient, ClientConfiguration

            from openfga_sdk import WriteAuthorizationModelRequest,
            TypeDefinition, Userset, Metadata, RelationMetadata,
            RelationReference


            async def main():
                configuration = ClientConfiguration(
                    api_url=os.environ.get("FGA_API_URL"),
                    store_id=os.environ.get("FGA_STORE_ID"),
                )
                async with OpenFgaClient(configuration) as fga_client:
                    body = WriteAuthorizationModelRequest(
                        schema_version="1.1",
                        type_definitions=[
                            TypeDefinition(
                                type="user",
                            ),
                            TypeDefinition(
                                type="document",
                                relations={
                                    "reader": Userset(
                                        this={},
                                    ),
                                },
                                metadata=Metadata(
                                    relations={
                                        "reader": RelationMetadata(
                                            directly_related_user_types=[
                                                RelationReference(
                                                    type="user",
                                                ),
                                            ],
                                        ),
                                    },
                                ),
                            ),
                        ],
                    )
                    response = await fga_client.write_authorization_model(body=body)

            asyncio.run(main())
        - lang: java
          label: Java
          source: |-
            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"));
                    var fgaClient = new OpenFgaClient(config);
                    
                    var body = new ApiClient().getObjectMapper()
                        .readValue("{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"user\"},{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}", WriteAuthorizationModelRequest.class);
                    var response = fgaClient.writeAuthorizationModel(body).get();
                }
            }
        - lang: bash
          label: curl
          source: >-
            # Set FGA_API_URL to the URL of your OpenFGA server.

            # Set FGA_STORE_ID to your store ID.

            # These examples use a server with authentication disabled.

            # For authenticated servers, see
            /docs/getting-started/setup-sdk-client.


            curl -X POST
            "$FGA_API_URL/stores/$FGA_STORE_ID/authorization-models" \
              -H "content-type: application/json" \
              -d '{
              "schema_version": "1.1",
              "type_definitions": [
                {
                  "type": "user"
                },
                {
                  "type": "document",
                  "relations": {
                    "reader": {
                      "this": {}
                    }
                  },
                  "metadata": {
                    "relations": {
                      "reader": {
                        "directly_related_user_types": [
                          {
                            "type": "user"
                          }
                        ]
                      }
                    }
                  }
                }
              ]
            }'
components:
  schemas:
    WriteAuthorizationModelBody:
      properties:
        conditions:
          additionalProperties:
            $ref: '#/components/schemas/Condition'
          type: object
        schema_version:
          type: string
        type_definitions:
          items:
            allOf:
              - $ref: '#/components/schemas/TypeDefinition'
              - type: object
          minItems: 1
          type: array
      required:
        - type_definitions
        - schema_version
      type: object
    WriteAuthorizationModelResponse:
      properties:
        authorization_model_id:
          example: 01G5JAVJ41T49E9TT3SKVS7X1J
          type: string
      required:
        - authorization_model_id
      type: object
    ValidationErrorMessageResponse:
      example:
        code: validation_error
        message: Generic validation error
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
      type: object
    UnauthenticatedResponse:
      example:
        code: unauthenticated
        message: unauthenticated
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
      type: object
    ForbiddenResponse:
      example:
        code: forbidden
        message: the principal is not authorized to perform the action
      properties:
        code:
          $ref: '#/components/schemas/AuthErrorCode'
        message:
          type: string
      type: object
    PathUnknownErrorMessageResponse:
      example:
        code: undefined_endpoint
        message: Endpoint not enabled
      properties:
        code:
          $ref: '#/components/schemas/NotFoundErrorCode'
        message:
          type: string
      type: object
    AbortedMessageResponse:
      example:
        code: '10'
        message: transaction conflict
      properties:
        code:
          type: string
        message:
          type: string
      type: object
    UnprocessableContentMessageResponse:
      example:
        code: throttled_timeout_error
        message: timeout due to throttling on complex request
      properties:
        code:
          $ref: '#/components/schemas/UnprocessableContentErrorCode'
        message:
          type: string
      type: object
    InternalErrorMessageResponse:
      example:
        code: internal_error
        message: Internal Server Error
      properties:
        code:
          $ref: '#/components/schemas/InternalErrorCode'
        message:
          type: string
      type: object
    Condition:
      properties:
        expression:
          description: A Google CEL expression, expressed as a string.
          type: string
        metadata:
          $ref: '#/components/schemas/ConditionMetadata'
        name:
          title: A unique name for the condition
          type: string
        parameters:
          additionalProperties:
            $ref: '#/components/schemas/ConditionParamTypeRef'
          description: A map of parameter names to the parameter's defined type reference.
          type: object
      required:
        - name
        - expression
      type: object
    TypeDefinition:
      properties:
        metadata:
          allOf:
            - $ref: '#/components/schemas/Metadata'
            - description: >-
                A map whose keys are the name of the relation and whose value is
                the Metadata for that relation.

                It also holds information around the module name and source file
                if this model was constructed

                from a modular model.
        relations:
          additionalProperties:
            $ref: '#/components/schemas/Userset'
          example:
            reader:
              union:
                child:
                  - this: {}
                  - computedUserset:
                      object: ''
                      relation: writer
            writer:
              this: {}
          type: object
        type:
          example: document
          type: string
      required:
        - type
      type: object
    ErrorCode:
      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
    AuthErrorCode:
      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
    NotFoundErrorCode:
      default: no_not_found_error
      enum:
        - no_not_found_error
        - undefined_endpoint
        - store_id_not_found
        - unimplemented
      type: string
    UnprocessableContentErrorCode:
      default: no_throttled_error_code
      enum:
        - no_throttled_error_code
        - throttled_timeout_error
      type: string
    InternalErrorCode:
      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
    ConditionMetadata:
      properties:
        module:
          type: string
        source_info:
          $ref: '#/components/schemas/SourceInfo'
      type: object
    ConditionParamTypeRef:
      properties:
        generic_types:
          items:
            allOf:
              - $ref: '#/components/schemas/ConditionParamTypeRef'
              - type: object
          type: array
        type_name:
          $ref: '#/components/schemas/TypeName'
      required:
        - type_name
      type: object
    Metadata:
      properties:
        module:
          type: string
        relations:
          additionalProperties:
            $ref: '#/components/schemas/RelationMetadata'
          type: object
        source_info:
          $ref: '#/components/schemas/SourceInfo'
      type: object
    Userset:
      properties:
        computedUserset:
          $ref: '#/components/schemas/ObjectRelation'
        difference:
          $ref: '#/components/schemas/v1.Difference'
        intersection:
          $ref: '#/components/schemas/Usersets'
        this:
          $ref: '#/components/schemas/DirectUserset'
        tupleToUserset:
          $ref: '#/components/schemas/v1.TupleToUserset'
        union:
          $ref: '#/components/schemas/Usersets'
      type: object
    SourceInfo:
      properties:
        file:
          type: string
      type: object
    TypeName:
      default: TYPE_NAME_UNSPECIFIED
      enum:
        - TYPE_NAME_UNSPECIFIED
        - TYPE_NAME_ANY
        - TYPE_NAME_BOOL
        - TYPE_NAME_STRING
        - TYPE_NAME_INT
        - TYPE_NAME_UINT
        - TYPE_NAME_DOUBLE
        - TYPE_NAME_DURATION
        - TYPE_NAME_TIMESTAMP
        - TYPE_NAME_MAP
        - TYPE_NAME_LIST
        - TYPE_NAME_IPADDRESS
      type: string
    RelationMetadata:
      properties:
        directly_related_user_types:
          items:
            allOf:
              - $ref: '#/components/schemas/RelationReference'
              - type: object
          type: array
        module:
          type: string
        source_info:
          $ref: '#/components/schemas/SourceInfo'
      type: object
    ObjectRelation:
      properties:
        object:
          type: string
        relation:
          type: string
      type: object
    v1.Difference:
      properties:
        base:
          $ref: '#/components/schemas/Userset'
        subtract:
          $ref: '#/components/schemas/Userset'
      required:
        - base
        - subtract
      type: object
    Usersets:
      properties:
        child:
          items:
            allOf:
              - $ref: '#/components/schemas/Userset'
              - type: object
          type: array
      required:
        - child
      type: object
    DirectUserset:
      description: |-
        A DirectUserset is a sentinel message for referencing
        the direct members specified by an object/relation mapping.
      type: object
    v1.TupleToUserset:
      properties:
        computedUserset:
          $ref: '#/components/schemas/ObjectRelation'
        tupleset:
          allOf:
            - $ref: '#/components/schemas/ObjectRelation'
            - title: The target object/relation
      required:
        - tupleset
        - computedUserset
      type: object
    RelationReference:
      description: >-
        RelationReference represents a relation of a particular object type
        (e.g. 'document#viewer').
      properties:
        condition:
          description: The name of a condition that is enforced over the allowed relation.
          type: string
        relation:
          example: member
          type: string
        type:
          example: group
          type: string
        wildcard:
          $ref: '#/components/schemas/Wildcard'
      required:
        - type
      type: object
    Wildcard:
      type: object

````