Hjarni Dashboard API

Counts and recent notes, in one call.

GitHub OpenAPI

Operations 1

GET /dashboard Get counts and recent notes #

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/hjarni-com:hjarni-com-dashboard-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

hjarni-com-dashboard-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hjarni REST Dashboard API
  version: 1.0.0
  description: Hjarni is a Markdown knowledge base that AI assistants and people share; this API reads and writes the same notes, folders (called containers) and tags that its MCP server exposes. Requests go to https://hjarni.com/api/v1 with a bearer token in the Authorization header, send and receive JSON, and list endpoints page with `page` and `per_page` and report totals in the `X-Total-Count`, `X-Page` and `X-Per-Page` headers. Requests are limited to 100 a minute per account across all of its tokens, and going over answers 429 with a `Retry-After` header.
  termsOfService: https://hjarni.com/terms
  contact:
    name: Hjarni
    email: evert@hjarni.com
    url: https://hjarni.com/docs/api
servers:
- url: https://hjarni.com/api/v1
security:
- bearerAuth: []
tags:
- name: Dashboard
  description: Counts and recent notes, in one call.
paths:
  /dashboard:
    get:
      operationId: getDashboard
      summary: Get counts and recent notes
      description: Returns note, folder and tag counts plus the five most recently created active notes, with bodies. A full-access token counts the person's personal notes and folders; an agent token counts what its grants reach, across spaces (`inbox_count` stays personal-only). Not paginated.
      tags:
      - Dashboard
      responses:
        '200':
          description: Counts and recent notes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  schemas:
    NoteAttachment:
      type: object
      description: A file attached to a note.
      required:
      - id
      - description
      - filename
      - content_type
      - byte_size
      - url
      - url_expires_at
      properties:
        id:
          type: integer
        description:
          type:
          - string
          - 'null'
        filename:
          type: string
        content_type:
          type:
          - string
          - 'null'
        byte_size:
          type: integer
        url:
          type: string
          format: uri
          description: Signed download link that works without a token until `url_expires_at` (15 minutes). Treat it as a credential and do not store it; fetch the note again for a fresh one.
        url_expires_at:
          type: string
          format: date-time
    TeamRef:
      type: object
      required:
      - id
      - name
      properties:
        id:
          type: integer
        name:
          type:
          - string
          - 'null'
    Dashboard:
      type: object
      required:
      - inbox_count
      - notes_count
      - archived_count
      - containers_count
      - tags_count
      - recent_notes
      properties:
        inbox_count:
          type: integer
          description: Active personal notes in no folder.
        notes_count:
          type: integer
          description: Active notes (not archived, not trashed).
        archived_count:
          type: integer
        containers_count:
          type: integer
          description: Active folders.
        tags_count:
          type: integer
        recent_notes:
          type: array
          description: The five most recently created active notes, with bodies.
          items:
            $ref: '#/components/schemas/NoteSummary'
    ContainerRef:
      type: object
      required:
      - id
      - name
      properties:
        id:
          type: integer
        name:
          type: string
    Error:
      type: object
      description: 'Every error response carries `error`. The generic statuses also carry `code`, `message` and `docs_url`: 401, a 403 for an agent token outside its grants, and any status answered for a raised error or an unknown endpoint (400, 404, 5xx). Plan-limit 403s carry `upgrade_url` instead. Some endpoint-specific errors carry `error` alone.'
      required:
      - error
      properties:
        status:
          type: integer
          description: The HTTP status again. Present on errors raised inside the app and on unknown endpoints (400, 404, 5xx), not on 401 or the 403s.
        error:
          type: string
          description: Human-readable message.
        errors:
          type: array
          items:
            type: string
          description: 'Only on a validation failure raised inside the app (422): one message per problem.'
        code:
          type: string
          description: 'Machine-readable code: `unauthorized` (401), `out_of_scope` (403, agent token), or for a raised error or unknown endpoint the snake_case name of the HTTP status, such as `bad_request`, `not_found`, `unprocessable_content` or `internal_server_error`.'
          examples:
          - unauthorized
          - out_of_scope
          - not_found
          - internal_server_error
        message:
          type: string
          description: What to do about it.
        docs_url:
          type: string
          format: uri
          description: The documentation page that explains this error.
        upgrade_url:
          type: string
          format: uri-reference
          description: Only on plan-limit 403s. A path on hjarni.com (relative, so prefix https://hjarni.com) to the checkout that lifts the limit.
        team_url:
          type: string
          format: uri-reference
          description: Only on the personal note-limit 403 from POST /notes. A relative path to creating a team, the other way past the personal limit.
    NoteSummary:
      type: object
      description: A note as list endpoints return it. `body` is left out when the request sets `exclude_body=true`; `last_edited_by` and `last_edited_by_agent` appear only once someone has edited the note; `team` appears only on team notes.
      required:
      - id
      - title
      - summary
      - summary_stale
      - source_url
      - archived
      - favorited
      - position
      - lock_version
      - created_at
      - updated_at
      - tag_list
      - tags
      - container
      - files
      properties:
        id:
          type: integer
        title:
          type: string
        body:
          type:
          - string
          - 'null'
          description: Markdown. `[[id:Title]]` is a wiki-link to another note.
        summary:
          type:
          - string
          - 'null'
          description: A short summary for scanning.
        summary_stale:
          type: boolean
          description: True when the body changed after the summary was written.
        source_url:
          type:
          - string
          - 'null'
        archived:
          type: boolean
        favorited:
          type: boolean
        position:
          type:
          - integer
          - 'null'
          description: Sort position among its siblings; null when unpositioned.
        lock_version:
          type: integer
          description: Increases on every save. Send it back as expected_lock_version to guard a write.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        last_edited_by:
          type:
          - string
          - 'null'
          description: Email address of whoever saved the note last.
        last_edited_by_agent:
          type:
          - string
          - 'null'
          description: Name of the agent or token that saved last, if one did.
        tag_list:
          type: string
          description: Tag names joined by a comma and a space, e.g. "planning, review".
        tags:
          type: array
          items:
            $ref: '#/components/schemas/TagRef'
        container:
          description: The folder the note is filed in; null for the inbox.
          oneOf:
          - $ref: '#/components/schemas/ContainerRef'
          - type: 'null'
        team:
          $ref: '#/components/schemas/TeamRef'
        files:
          type: array
          items:
            $ref: '#/components/schemas/NoteAttachment'
    TagRef:
      type: object
      required:
      - id
      - name
      properties:
        id:
          type: integer
        name:
          type: string
  responses:
    TooManyRequests:
      description: Over the rate limit of 100 requests a minute per account, counted across all of its tokens (counters are kept per server process, so the ceiling actually enforced can be somewhat higher). Wait the number of seconds in `Retry-After`. The body has `error` only.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Rate limit exceeded. Retry after 12 seconds.
    Unauthorized:
      description: The bearer token is missing, unknown or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Unauthorized
            code: unauthorized
            message: 'Missing or invalid token. Send it as Authorization: Bearer <token>; tokens are created in Settings > Connections.'
            docs_url: https://hjarni.com/docs/api#auth
  headers:
    Retry-After:
      description: Seconds until the current rate-limit window ends.
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An API token in `Authorization: Bearer <token>`. Tokens are created in Settings > Connections, or issued to an assistant through the OAuth flow. A new token made in Settings reaches only the folders it is given, at Read or Write per folder, unless it is made with Everything I can reach (see https://hjarni.com/docs/agent-tokens); a token issued through OAuth acts with the person''s full access. A missing, unknown or expired token answers 401.'
externalDocs:
  url: https://hjarni.com/docs/api