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.
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