Skip to content

Manage organizations, entitlements and readers

An organization's entitlements decide what its readers see. Load them from a seed file, or change them through the admin API.

  • An organization has a slug and a name.
  • Its entitlements are the products and features it holds and the version it runs, exactly the fields of a preview context. Without entitlements, its readers see "No access yet".
  • A reader belongs to one organization and is identified by email. Sign-in links the email to the identity provider's account the first time.
  • A staff reader (you and your team) sees everything the build publishes, on the newest release line or their organization's, with each condition marked, as in the previewer. Content removed at build time stays removed. Only the admin API (PUT /admin/api/readers/:id/staff) and seed files set it: entitlement sync from billing or a CRM never grants or revokes it, and a reader cannot set it.
  1. Write a seed file.
    repos:
      - fullName: acme/docs              # owner/name as GitHub sends it
        sourceUrl: https://github.com/acme/docs.git
        # installationId: 12345678       # GitHub App installation, for private repos
        releaseRefs: [main, 'v*']        # branches and tags that publish (default [main])
        docsPath: .                      # docs root inside the repository (default .)
    
    orgs:
      - slug: acme
        name: Acme Corp
        entitlements:
          products: [core]
          features: []
          version: '0.1'                 # picks the 0.x docs
        readers: [ann@acme.example]
      - slug: globex
        name: Globex
        entitlements:
          products: [hosted, embed]
          version: '0.1'
        readers:
          - email: gus@globex.example
            name: Gus
      - slug: docs-team                  # your own team
        name: Docs team
        readers:
          - email: owner@example.com
            staff: true                  # the unfiltered staff view
  2. Load it with the seed command.
    opend-server seed /seed/seed.yaml
    # with Docker Compose:
    docker compose -f deploy/docker-compose.yml run --rm migrate seed /seed/seed.yaml

    Everything is upserted in one transaction, so the file can be applied again after each change. Seeding never deletes anything.

  3. For day-to-day changes, use the admin API.
    H="authorization: Bearer $OPEND_ADMIN_TOKEN"
    # Change what an organization may see
    curl -X PUT "$PUBLIC_URL/admin/api/orgs/acme/entitlements" -H "$H" -H 'content-type: application/json' \
      -d '{"products":["core","embed"],"features":[],"version":"0.1"}'
    # Add a reader, or move one to another organization
    curl -X POST "$PUBLIC_URL/admin/api/readers" -H "$H" -H 'content-type: application/json' \
      -d '{"orgSlug":"acme","email":"bo@acme.example","name":"Bo"}'
    # Give a reader the staff view (reader id from GET /admin/api/readers)
    curl -X PUT "$PUBLIC_URL/admin/api/readers/7/staff" -H "$H" -H 'content-type: application/json' \
      -d '{"staff":true}'

Entitlement changes take effect at once on every replica: the server is notified through Postgres and clears its caches. Every change through the API or a seed is written to the audit log. Values are tokens (letters, digits, _, ., :, -), and the version is a version number such as 0.1. Use the same product and feature values the docs declare in opend.config.yaml.