FairePlace Mandates API

Management mandates (mandats de gestion) between a principal (owner/lessee) and a mandataire: create, attach a document, activate, and revoke.

GitHub OpenAPI

Operations 6

GET /mandates List mandates #
POST /mandates Create a mandate #
GET /mandates/{id} Get a mandate #
POST /mandates/{id}/attach-document Attach a document to a mandate #
POST /mandates/{id}/activate Activate a mandate #
POST /mandates/{id}/revoke Revoke a mandate #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/faireplace-com:faireplace-com-mandates-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

faireplace-com-mandates-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: FairePlace Property Management Mandates API
  description: 'Comprehensive API for managing properties, leases, tenants, and all aspects of real estate management.

    Built with Rust and Actix-web following hexagonal architecture principles.


    ## Authentication

    This API uses API keys for authentication with tenant-based isolation.


    ## Base URL

    - Production: `https://api.faireplace.com/api`'
  version: 1.0.0
  contact:
    name: FairePlace API Support
    email: api-support@faireplace.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
- url: https://api.faireplace.com/api
  description: Production server
security:
- BearerAuth: []
tags:
- name: Mandates
  description: 'Management mandates (mandats de gestion) between a principal (owner/lessee)

    and a mandataire: create, attach a document, activate, and revoke.'
paths:
  /mandates:
    get:
      operationId: listMandates
      summary: List mandates
      description: 'Lists the mandates visible to the authenticated user, filtered by their role.


        ## Role filter


        The `role` query parameter controls which mandates are returned:

        - `mandataire` (default): mandates where the user is the **delegate**

        - `principal`: mandates where the user is the **principal** (the person who granted the mandate)


        An empty or missing `role` is treated as `mandataire`. Any other value returns `400`.


        ## Multi-tenant isolation


        Mandates are automatically scoped to the `tenant_id` extracted from the JWT.


        ## Usage Example


        ```bash

        curl -X GET "https://api.faireplace.com/api/mandates?role=mandataire" \

        -H "Authorization: Bearer YOUR_API_KEY"

        ```


        **Response**:

        ```json

        [

        {

        "id": "770e8400-e29b-41d4-a716-446655440222",

        "tenant_id": "tenant_123",

        "mandataire_auth_user_id": "user_456",

        "principal": {

        "person_id": "550e8400-e29b-41d4-a716-446655440000",

        "kind": "owner",

        "display_name": "Jean Dupont"

        },

        "scope": ["initiate_signature", "sign_on_behalf"],

        "valid_from": "2026-01-01",

        "valid_until": "2026-12-31",

        "mandate_document": { "media_id": null, "signed": false },

        "status": "draft",

        "created_at": "2026-01-01T10:00:00Z",

        "updated_at": "2026-01-01T10:00:00Z",

        "revoked_at": null,

        "revoke_reason": null

        }

        ]

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      parameters:
      - name: role
        in: query
        required: false
        description: 'Filter mandates by the user''s role.


          - `mandataire` (default): user is the delegate

          - `principal`: user is the principal

          '
        schema:
          type: string
          enum:
          - mandataire
          - principal
          default: mandataire
        example: mandataire
      responses:
        '200':
          description: List of mandates (empty array if none).
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Mandate'
        '400':
          description: Invalid `role` value.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      operationId: createMandate
      summary: Create a mandate
      description: 'Creates a new mandate in `draft` status.


        The `tenant_id` and `mandataire_auth_user_id` are derived from the JWT and

        must not be supplied in the body.


        ## Validations


        - `principal_kind` must be `owner` or `lessee`

        - `scope` must be a non-empty array of valid scope values

        - `valid_until`, when present, must be strictly after `valid_from`


        ## Usage Example


        ```bash

        curl -X POST https://api.faireplace.com/api/mandates \

        -H "Authorization: Bearer YOUR_API_KEY" \

        -H "Content-Type: application/json" \

        -d ''{

        "principal_person_id": "550e8400-e29b-41d4-a716-446655440000",

        "principal_kind": "owner",

        "scope": ["initiate_signature", "sign_on_behalf"],

        "valid_from": "2026-01-01",

        "valid_until": "2026-12-31"

        }''

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMandateRequest'
            examples:
              owner_mandate:
                summary: Mandate for an owner
                value:
                  principal_person_id: 550e8400-e29b-41d4-a716-446655440000
                  principal_kind: owner
                  scope:
                  - initiate_signature
                  - sign_on_behalf
                  valid_from: '2026-01-01'
                  valid_until: '2026-12-31'
      responses:
        '201':
          description: Mandate created (status `draft`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mandate'
        '400':
          description: 'Validation error (invalid `principal_kind`, empty/unknown `scope`,

            or `valid_until` not after `valid_from`).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /mandates/{id}:
    get:
      operationId: getMandate
      summary: Get a mandate
      description: 'Retrieves a single mandate by its identifier.


        ```bash

        curl -X GET https://api.faireplace.com/api/mandates/770e8400-e29b-41d4-a716-446655440222 \

        -H "Authorization: Bearer YOUR_API_KEY"

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The mandate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mandate'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /mandates/{id}/attach-document:
    post:
      operationId: attachDocumentMandate
      summary: Attach a document to a mandate
      description: 'Attaches a signed document (media) to a mandate. When the attached

        document is signed and the mandate is within its validity window, the

        mandate is **atomically activated** (status becomes `active`).


        ```bash

        curl -X POST https://api.faireplace.com/api/mandates/770e8400-e29b-41d4-a716-446655440222/attach-document \

        -H "Authorization: Bearer YOUR_API_KEY" \

        -H "Content-Type: application/json" \

        -d ''{ "media_id": "660e8400-e29b-41d4-a716-446655440111" }''

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AttachMandateDocumentRequest'
      responses:
        '200':
          description: The updated mandate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mandate'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /mandates/{id}/activate:
    post:
      operationId: activateMandate
      summary: Activate a mandate
      description: 'Activates a `draft` mandate (status becomes `active`). Activation

        requires a signed document to be attached and the mandate to be within

        its validity window; otherwise the request is rejected.


        No request body is required.


        ```bash

        curl -X POST https://api.faireplace.com/api/mandates/770e8400-e29b-41d4-a716-446655440222/activate \

        -H "Authorization: Bearer YOUR_API_KEY"

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The activated mandate (status `active`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mandate'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /mandates/{id}/revoke:
    post:
      operationId: revokeMandate
      summary: Revoke a mandate
      description: 'Revokes a mandate (status becomes `revoked`). An optional `reason`

        (max 500 chars) can be provided.


        ```bash

        curl -X POST https://api.faireplace.com/api/mandates/770e8400-e29b-41d4-a716-446655440222/revoke \

        -H "Authorization: Bearer YOUR_API_KEY" \

        -H "Content-Type: application/json" \

        -d ''{ "reason": "Mandat remplacé par un nouveau" }''

        ```'
      tags:
      - Mandates
      security:
      - BearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeMandateRequest'
      responses:
        '200':
          description: The revoked mandate (status `revoked`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Mandate'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    MandateDocumentDto:
      type: object
      description: The document backing the mandate.
      required:
      - signed
      properties:
        media_id:
          type:
          - string
          - 'null'
          format: uuid
          description: Identifier of the attached media (the signed mandate document).
          example: 660e8400-e29b-41d4-a716-446655440111
        signed:
          type: boolean
          description: Whether the mandate document has been signed.
          example: false
    PrincipalDto:
      type: object
      description: The principal (person) on whose behalf the mandate is held.
      required:
      - person_id
      - kind
      - display_name
      properties:
        person_id:
          type: string
          format: uuid
          description: Identifier of the principal person (owner or lessee).
          example: 550e8400-e29b-41d4-a716-446655440000
        kind:
          $ref: '#/components/schemas/PrincipalKind'
        display_name:
          type: string
          description: 'Display name of the principal. On creation this is a placeholder

            (`(à charger)`) until the principal details are loaded.

            '
          example: Jean Dupont
    Error:
      type: object
      description: "The error envelope returned by every authenticated endpoint.\n\nTwo things are worth knowing before you write your error handling:\n\n- **`code` is a symbolic string, not a number.** The numeric HTTP status is\n  in `status`. Branch on `code`: it is stable, and show `message`, which\n  is written for humans and may be reworded without notice.\n- The public guest-signature endpoints use a **different, flatter shape**\n  (`{ \"error_code\": …, \"message\": … }`, no `error` wrapper), because they\n  are consumed by a page that has no session. Their responses document it\n  inline.\n\nThe `X-Request-Id` response header carries the request identifier: quote it\nwhen reporting a problem. It is a header, not a body field.\n"
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          - status
          properties:
            code:
              type: string
              description: Stable symbolic code. Branch on this.
              enum:
              - NOT_FOUND
              - UNAUTHORIZED
              - VALIDATION_ERROR
              - DATABASE_ERROR
              - BUSINESS_ERROR
              - STORAGE_ERROR
              - CONFIG_ERROR
              - FORBIDDEN
              - CONFLICT
              - PARSE_ERROR
              - SERIALIZATION_ERROR
              - AUTHENTICATION_ERROR
              - AUTHORIZATION_ERROR
              - EXTERNAL_SERVICE_ERROR
              - RATE_LIMIT_EXCEEDED
              - PAYMENT_REQUIRED
              - PLAN_LIMIT_REACHED
              - GONE
              - BAD_REQUEST
              - INTERNAL_ERROR
              - INTERNAL_SERVER_ERROR
              example: NOT_FOUND
            message:
              type: string
              description: 'Human-readable explanation, most often in French. Safe to display,

                not safe to parse.

                '
              example: Lease not found
            status:
              type: integer
              description: The HTTP status code, repeated in the body.
              example: 404
            details:
              type: object
              additionalProperties: true
              description: 'Extra machine-readable context. Only present on some errors: on

                `RATE_LIMIT_EXCEEDED` it carries `retry_after_seconds`.

                '
              example:
                retry_after_seconds: 12
    PrincipalKind:
      type: string
      description: 'Kind of principal (the person granting the mandate).

        '
      enum:
      - owner
      - lessee
      x-enumDescriptions:
        owner: The principal is a property owner.
        lessee: The principal is a lessee (tenant).
      example: owner
    AttachMandateDocumentRequest:
      type: object
      description: 'Request to attach a (signed) document to a mandate. Attaching a valid

        signed document atomically activates the mandate.

        '
      required:
      - media_id
      properties:
        media_id:
          type: string
          format: uuid
          description: Identifier of the media (document) to attach.
          example: 660e8400-e29b-41d4-a716-446655440111
    RevokeMandateRequest:
      type: object
      description: Request to revoke a mandate.
      properties:
        reason:
          type:
          - string
          - 'null'
          maxLength: 500
          description: Optional free-text reason for the revocation.
          example: Mandat remplacé par un nouveau
    MandateStatus:
      type: string
      description: 'Lifecycle status of a mandate.


        Valid transitions: `draft → active`, `draft → revoked`,

        `active → revoked`, `active → expired`.

        '
      enum:
      - draft
      - active
      - revoked
      - expired
      example: draft
    CreateMandateRequest:
      type: object
      description: 'Request to create a new mandate. The created mandate starts in `draft`

        status. The `tenant_id` and `mandataire_auth_user_id` are derived from the

        JWT, never from the body.

        '
      required:
      - principal_person_id
      - principal_kind
      - scope
      - valid_from
      properties:
        principal_person_id:
          type: string
          format: uuid
          description: Identifier of the principal (owner or lessee) person.
          example: 550e8400-e29b-41d4-a716-446655440000
        principal_kind:
          $ref: '#/components/schemas/PrincipalKind'
        scope:
          type: array
          minItems: 1
          description: Non-empty list of delegated permissions.
          items:
            $ref: '#/components/schemas/MandateScope'
          example:
          - initiate_signature
          - sign_on_behalf
        valid_from:
          type: string
          format: date
          description: Start date of validity (ISO 8601).
          example: '2026-01-01'
        valid_until:
          type:
          - string
          - 'null'
          format: date
          description: 'Optional end date. Must be strictly after `valid_from` when provided.

            '
          example: '2026-12-31'
    Mandate:
      type: object
      description: 'A mandate delegating one or more permissions from a principal (owner or

        lessee) to a mandataire (the authenticated user). A mandate becomes

        `active` once a signed document is attached and it is within its validity

        window.

        '
      required:
      - id
      - tenant_id
      - mandataire_auth_user_id
      - principal
      - scope
      - valid_from
      - mandate_document
      - status
      - created_at
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Unique mandate identifier.
          example: 770e8400-e29b-41d4-a716-446655440222
        tenant_id:
          type: string
          description: Tenant identifier (multi-tenant isolation).
          example: tenant_123
        mandataire_auth_user_id:
          type: string
          description: Auth user ID of the mandataire (extracted from the JWT).
          example: user_456
        principal:
          $ref: '#/components/schemas/PrincipalDto'
        scope:
          type: array
          description: Ordered list of delegated permissions.
          items:
            $ref: '#/components/schemas/MandateScope'
          example:
          - initiate_signature
          - sign_on_behalf
        valid_from:
          type: string
          format: date
          description: Start date of validity (ISO 8601, `YYYY-MM-DD`).
          example: '2026-01-01'
        valid_until:
          type:
          - string
          - 'null'
          format: date
          description: 'End date of validity (ISO 8601). `null` means no end date.

            When set, must be strictly after `valid_from`.

            '
          example: '2026-12-31'
        mandate_document:
          $ref: '#/components/schemas/MandateDocumentDto'
        status:
          $ref: '#/components/schemas/MandateStatus'
        created_at:
          type: string
          format: date-time
          description: Creation timestamp (ISO 8601).
          example: '2026-01-01T10:00:00Z'
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp (ISO 8601).
          example: '2026-01-01T10:00:00Z'
        revoked_at:
          type:
          - string
          - 'null'
          format: date-time
          description: Revocation timestamp, or `null` if not revoked.
          example: null
        revoke_reason:
          type:
          - string
          - 'null'
          description: Free-text reason for revocation (max 500 chars), or `null`.
          example: null
    MandateScope:
      type: string
      description: 'A single permission delegated by the mandate.

        '
      enum:
      - initiate_signature
      - sign_on_behalf
      - collect_rent
      - manage_property
      x-enumDescriptions:
        initiate_signature: Initiate a signature process on behalf of the principal.
        sign_on_behalf: Sign documents on behalf of the principal.
        collect_rent: Collect rent on behalf of the principal.
        manage_property: Manage the property on behalf of the principal.
      example: sign_on_behalf
  responses:
    Forbidden:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    UnprocessableEntity:
      description: Unprocessable Entity
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalServerError:
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key with fp_* prefix, passed as Bearer token
    WorkerApiKey:
      type: apiKey
      in: header
      name: X-API-Key
    WorkerBearer:
      type: http
      scheme: bearer
      bearerFormat: Worker