Skip to content
LogoLogo

Your first API call

In this tutorial we make your first calls to the Picked management API. We start with a ping, then authenticate, then read your user and make an organization.

At the end you have an access token and two answers from the API.

Before you start

  • A Picked account, with an email address and a password.
  • curl, or any HTTP client.

Playground

Read the API and run a query in the GraphQL Playground.

API endpoint

All requests go to a single endpoint:

POST https://api.picked.app/api/graphql

Every request must use the POST method. The JSON body must hold a query field, and it can also hold a variables field:

{
  "query": "query { ... }",
  "variables": { }
}

Set the Content-Type header to application/json on every request.

curl -X POST https://api.picked.app/api/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ ping }"}'

Ping the API

Check that the API is reachable with the ping query. This query needs no authentication.

query {
  ping
}

Response:

{
  "data": {
    "ping": "pong"
  }
}

This response means that the API is ready.

Authenticate

Most operations need an access token. To get one, create a session with your email address and your password.

mutation {
  sessionCreate(input: {
    email: "you@example.com"
    password: "your-password"
  }) {
    session {
      accessToken
      refreshToken
      expiresAt
      aal
      user {
        mfa { required enrolled }
      }
    }
  }
}

A successful response returns a Session with an accessToken and a refreshToken:

{
  "data": {
    "sessionCreate": {
      "session": {
        "accessToken": "eyJhbGciOiJIUzI1NiIs...",
        "refreshToken": "v1.refresh-token...",
        "expiresAt": "2025-01-15T12:00:00Z",
        "aal": "AAL1",
        "user": {
          "mfa": { "required": false, "enrolled": false }
        }
      }
    }
  }
}

When required is true, the token can only read user and call the MFA mutations until you verify a code from an authenticator app. See How to set up MFA.

For a server-to-server integration, use API key authentication and not a session token.

Make an authenticated query

Pass the access token in the Authorization header as a Bearer token:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

You can now query a resource that needs authentication. This example reads your user profile:

query {
  user {
    id
    email
    createdAt
    organizations(first: 5) {
      edges {
        node {
          id
          name
        }
      }
    }
  }
}

Make a mutation

A mutation follows the same pattern. Send a POST request with the Authorization header. This example creates an organization:

mutation {
  organizationCreate(input: {
    name: "My Company"
    slug: "my-company"
  }) {
    organization {
      id
      name
      slug
    }
  }
}

Response:

{
  "data": {
    "organizationCreate": {
      "organization": {
        "id": "org_abc123",
        "name": "My Company",
        "slug": "my-company"
      }
    }
  }
}

Every mutation takes an input argument and returns a payload object. On success the payload holds the resource that the mutation created or updated. On failure the errors array at the top level holds the errors.

Errors

When something goes wrong, the API returns the errors in the standard GraphQL errors array:

{
  "data": null,
  "errors": [
    {
      "message": "Invalid credentials",
      "extensions": {
        "code": "INVALID_CREDENTIALS"
      }
    }
  ]
}

Read the extensions.code field. It holds an error code that your code can act on. See the Errors guide for the full list of codes.

What you built

You authenticated against the management API, read your own user, and created an organization. Every other operation follows the same shape: a POST to one endpoint, with your token in the Authorization header.

Where to go next

  • Authentication — an email address and a password, OAuth, magic links, MFA, API keys, and how to control a session.
  • Authorization and Scopes — what each role can reach, and how a scope controls a permission.
  • Pagination — how to move through a large result with a cursor.
  • Errors — every error code that the API can return.