Harbor
Developer docs menu

Start here

Getting started

Everything the Harbor app can do, your code can do. Here's your first API call in about five minutes.

The Harbor API is a standard REST API over HTTPS. Requests and responses are JSON. You authenticate with a personal access token (for your own scripts) or an OAuth app (for integrations other people install). There’s also a first-class command-line tool and an agent skill for your AI.

Base URL

All API requests go to:

https://app.harbor.my/api/v1

The API is versioned in the path (/api/v1). We’ll add new versions rather than break this one.

1. Get a token

Sign in to Harbor, open Settings → Developer, and click Create token. Give it a name, pick the scopes it needs, and copy the value — it starts with hbp_ and is shown only once.

Full token & OAuth guide →

2. Make your first request

Set your token as an environment variable so you never paste it into a command:

export HARBOR_TOKEN="hbp_your_token_here"

Now fetch your notes:

curl https://app.harbor.my/api/v1/notes \
  -H "Authorization: Bearer $HARBOR_TOKEN"

You’ll get back a paginated list:

{
  "data": [
    {
      "id": "9c2e7f1a-0b3d-4e6f-8a12-5c7d9e0f1a2b",
      "title": "Welcome to Harbor",
      "notebook_id": "5b1f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
      "created_at": 1752600000000,
      "updated_at": 1752600000000
    }
  ],
  "paging": { "total": 1, "limit": 100, "offset": 0 }
}

That’s it — you’re talking to your second brain over HTTP.

3. Create a note

curl -X POST https://app.harbor.my/api/v1/notes \
  -H "Authorization: Bearer $HARBOR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Created from the API",
    "content": "# Hello Harbor\n\nThis note was created with a POST request.",
    "format": "markdown"
  }'

The response is the created note, including its new id.

In your language of choice

Python

import os, requests

harbor = requests.Session()
harbor.headers["Authorization"] = f"Bearer {os.environ['HARBOR_TOKEN']}"
BASE = "https://app.harbor.my/api/v1"

# List notes
notes = harbor.get(f"{BASE}/notes").json()
print(notes["paging"]["total"], "notes")

# Create one
new = harbor.post(f"{BASE}/notes", json={
    "title": "Created from Python",
    "content": "# Hello\n\nFrom a script.",
    "format": "markdown",
}).json()
print("created", new["data"]["id"])

JavaScript (Node or the browser)

const BASE = "https://app.harbor.my/api/v1";
const token = process.env.HARBOR_TOKEN;

const res = await fetch(`${BASE}/notes`, {
  headers: { Authorization: `Bearer ${token}` },
});
const { data, paging } = await res.json();
console.log(`${paging.total} notes`);

await fetch(`${BASE}/notes`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Created from JS",
    content: "# Hello\n\nFrom fetch().",
    format: "markdown",
  }),
});

Go

package main

import (
	"bytes"
	"fmt"
	"net/http"
	"os"
)

const base = "https://app.harbor.my/api/v1"

func main() {
	token := os.Getenv("HARBOR_TOKEN")

	req, _ := http.NewRequest("POST", base+"/notes", bytes.NewBufferString(`{
		"title": "Created from Go",
		"content": "# Hello\n\nFrom net/http.",
		"format": "markdown"
	}`))
	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	fmt.Println("status", res.Status)
}

Prefer the terminal?

Everything here is one command away with the Harbor CLI:

brew tap HarborMyNotes/harbor https://github.com/HarborMyNotes/harbor-cli
brew install harbor
harbor login
harbor notes list

Next steps

  • Authentication — personal access tokens, OAuth apps, and scopes
  • Conventions — pagination, timestamps, and the response envelope
  • Errors — status codes and the error format
  • API reference — every endpoint, with examples