Skip to content

Transport Layers

Grant exposes two API transports that share the same backend (handlers, services, repositories):

TransportEndpointDocumentation
REST/api/*Swagger UI
GraphQL/graphqlApollo Sandbox

Both accept Authorization: Bearer <token> for authentication and use the same scope: { tenant, id } pattern for multi-tenancy.

When to Use Which

Use caseRecommendedWhy
OAuth flows (GitHub login)RESTRequires browser redirects
CI/CD scripts, curlRESTSimpler to call from shell
Swagger explorationRESTInteractive docs out of the box
Token exchange (API keys)RESTPOST /api/auth/token is REST-only
JWKS discoveryRESTStandard .well-known endpoint
Web dashboardGraphQLField selection, batching, Apollo Client
Complex nested queriesGraphQLQuery exactly the fields you need
Code generationGraphQLTypes from @grantjs/schema codegen

Endpoint Parity

Most operations are available in both transports. A few are REST-only due to their nature (browser redirects, file downloads, well-known discovery). No operations are GraphQL-only.

REST-Only Endpoints

EndpointPurpose
GET /api/auth/githubInitiate GitHub OAuth — redirects browser to GitHub
GET /api/auth/github/callbackHandle GitHub OAuth callback — redirect handler
POST /api/auth/cli-callbackExchange one-time CLI code for session tokens
POST /api/auth/tokenExchange API key credentials for JWT
POST /api/auth/is-authorizedAuthorization check (used by @grantjs/server SDK)
GET /api/me/exportGDPR data export (returns file download)
GET /.well-known/jwks.jsonJWKS public key discovery (+ scoped variants)
GET /api/signing-keysList signing keys for a project
POST /api/signing-keys/rotateRotate a project signing key

Shared Operations

All CRUD operations for these resources are available in both REST and GraphQL:

Organizations, Projects, Users, Roles, Groups, Permissions, Resources, Tags, API Keys, Organization Invitations, Organization Members.

Authentication mutations (login, register, refresh, logout, verify email, password reset) are also available in both.

Scoping

Both transports use the same scope model. The only difference is how scope is passed:

REST — Query parameters for reads, request body for writes:

bash
# GET (query params)
GET /api/roles?scopeId=<orgId>:<projectId>&tenant=organizationProject

# POST (body)
POST /api/roles
{ "name": "Editor", "scope": { "tenant": "organizationProject", "id": "<orgId>:<projectId>" } }

GraphQL — Always in the input argument:

graphql
mutation {
  createRole(
    input: { name: "Editor", scope: { tenant: organizationProject, id: "<orgId>:<projectId>" } }
  ) {
    id
    name
  }
}

Authentication

Both transports accept the same JWT token:

http
Authorization: Bearer <accessToken>

GraphQL additionally supports cookie-based authentication (HttpOnly refresh token cookie) for the web dashboard. The REST API uses the same cookie mechanism for browser-based sessions.

Error Formats

Errors carry the same code values across both transports, but the response envelope differs:

REST:

json
{
  "error": "User not found",
  "code": "NOT_FOUND"
}

GraphQL:

json
{
  "data": null,
  "errors": [
    {
      "message": "User not found",
      "extensions": { "code": "NOT_FOUND" }
    }
  ]
}

See Error Handling for the full reference.

GraphQL Sandbox

In non-production environments, the GraphQL endpoint at /graphql serves the Apollo Sandbox — an embedded IDE for building and testing queries.

To authenticate in the sandbox:

  1. Open http://localhost:4000/graphql
  2. Click the Headers tab at the bottom
  3. Add: { "Authorization": "Bearer <accessToken>" }
  4. Write and execute queries/mutations

Introspection

Schema introspection is enabled by default in non-production environments (APOLLO_INTROSPECTION=true). It is automatically disabled in production.

GraphQL Operations

The GraphQL API provides 19 queries and 56 mutations. Key operation groups:

GroupQueriesMutations
Authenticationme, isAuthorizedlogin, register, refreshSession, verifyEmail, resetPassword, ...
Organizationsorganizations, organizationMembers, organizationInvitationscreateOrganization, inviteMember, acceptInvitation, ...
ProjectsprojectscreateProject, updateProject, deleteProject
RBACroles, groups, permissions, resourcesCRUD for each
UsersuserscreateUser, updateUser, deleteUser
API KeysapiKeys, signingKeyscreateApiKey, exchangeApiKey, rotateSigningKey, ...
TagstagscreateTag, updateTag, deleteTag
MemyUserSessions, myUserAuthenticationMethods, myUserDataExportchangeMyPassword, uploadMyUserPicture, ...

The full schema is available via introspection or through the @grantjs/schema package.


Related:

Released under the MIT License.