mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-12 08:54:00 +02:00
955 lines
29 KiB
HTML
955 lines
29 KiB
HTML
<!doctype html>
|
|
<html>
|
|
|
|
<!--
|
|
|
|
!!! WARNING !!!
|
|
|
|
This file was auto-generated from readme/api.md and any manual change
|
|
made to it will be overwritten. To make a change to this file please modify
|
|
the source Markdown file:
|
|
|
|
https://github.com/laurent22/joplin/blob/master/readme/api.md
|
|
|
|
-->
|
|
|
|
<head>
|
|
<title>REST API | Joplin</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="https://joplinapp.org/css/bootstrap.min.css">
|
|
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
|
|
<!-- <link rel="stylesheet" href="https://joplinapp.org/css/fontawesome-all.min.css"> -->
|
|
<link rel="stylesheet" href="https://joplinapp.org/css/fork-awesome.min.css">
|
|
<script src="https://joplinapp.org/js/jquery-3.2.1.slim.min.js"></script>
|
|
<style>
|
|
body {
|
|
background-color: #F1F1F1;
|
|
color: #333333;
|
|
}
|
|
table {
|
|
margin-bottom: 1em;
|
|
}
|
|
td, th {
|
|
padding: .8em;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
.page-markdown table pre,
|
|
.page-markdown table blockquote {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.page-markdown table pre,
|
|
.page-markdown table blockquote {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.page-markdown table pre {
|
|
background-color: rgba(0,0,0,0);
|
|
border: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
h1, h2 {
|
|
border-bottom: 1px solid #eaecef;
|
|
padding-bottom: 0.3em;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
font-weight: 600;
|
|
font-size: 2em;
|
|
margin-bottom: 16px;
|
|
}
|
|
h2 {
|
|
font-size: 1.6em;
|
|
}
|
|
h3 {
|
|
font-size: 1.3em;
|
|
}
|
|
code {
|
|
color: black;
|
|
background-color: #eee;
|
|
border: 1px solid #ccc;
|
|
font-size: .85em;
|
|
}
|
|
pre code {
|
|
border: none;
|
|
}
|
|
pre {
|
|
font-size: .85em;
|
|
}
|
|
blockquote {
|
|
font-size: 1em;
|
|
color: #555;
|
|
};
|
|
#toc ul {
|
|
margin-bottom: 10px;
|
|
}
|
|
#toc {
|
|
padding-bottom: 1em;
|
|
}
|
|
.title {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.title-icon {
|
|
display: flex;
|
|
height: 1em;
|
|
}
|
|
.title-text {
|
|
display: flex;
|
|
font-weight: normal;
|
|
margin-bottom: .2em;
|
|
margin-left: .5em;
|
|
}
|
|
.sub-title {
|
|
font-weight: normal;
|
|
}
|
|
.container {
|
|
background-color: white;
|
|
padding: 0;
|
|
box-shadow: 0 10px 20px #888888;
|
|
}
|
|
table.screenshots {
|
|
margin-top: 2em;
|
|
margin-bottom: 2em;
|
|
}
|
|
table.screenshots th {
|
|
height: 3em;
|
|
text-align: center;
|
|
}
|
|
table.screenshots th,
|
|
table.screenshots td {
|
|
border: 1px solid #C2C2C2;
|
|
}
|
|
img[align="left"] {
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
.mobile-screenshot {
|
|
height: 40em;
|
|
padding: 1em;
|
|
}
|
|
.cli-screenshot-wrapper {
|
|
background-color: black;
|
|
vertical-align: top;
|
|
padding: 1em 2em 1em 1em;
|
|
}
|
|
.cli-screenshot {
|
|
font-family: "Monaco", "Inconsolata", "CONSOLAS", "Deja Vu Sans Mono", "Droid Sans Mono", "Andale Mono", monospace;
|
|
background-color: black;
|
|
color: white;
|
|
border: none;
|
|
}
|
|
.cli-screenshot .prompt {
|
|
color: #48C2F0;
|
|
}
|
|
.top-screenshot {
|
|
margin-top: 2em;
|
|
text-align: center;
|
|
}
|
|
.header {
|
|
position: relative;
|
|
padding-left: 2em;
|
|
padding-right: 2em;
|
|
padding-top: 1em;
|
|
padding-bottom: 1em;
|
|
color: white;
|
|
background-color: #2B2B3D;
|
|
}
|
|
.header a h1 {
|
|
color: white;
|
|
}
|
|
.header a:hover {
|
|
text-decoration: none;
|
|
}
|
|
.content {
|
|
padding-left: 2em;
|
|
padding-right: 2em;
|
|
padding-bottom: 2em;
|
|
padding-top: 2em;
|
|
}
|
|
.forkme {
|
|
position: absolute;
|
|
right: 0;
|
|
top:0;
|
|
}
|
|
.nav-wrapper {
|
|
position: relative;
|
|
width: inherit;
|
|
}
|
|
.nav {
|
|
background-color: black;
|
|
display: table;
|
|
width: inherit;
|
|
}
|
|
.nav.sticky {
|
|
position:fixed;
|
|
top: 0;
|
|
width: inherit;
|
|
box-shadow: 0 0 10px #000000;
|
|
}
|
|
.nav a {
|
|
color: white;
|
|
display: inline-block;
|
|
padding: .6em .9em .6em .9em;
|
|
}
|
|
.nav ul {
|
|
padding-left: 2em;
|
|
margin-bottom: 0;
|
|
display: table-cell;
|
|
/* min-width: 250px; */
|
|
/* For GSoC: */
|
|
min-width: 470px;
|
|
}
|
|
.nav ul li {
|
|
display: inline-block;
|
|
padding: 0;
|
|
}
|
|
.nav li.selected {
|
|
background-color: #222;
|
|
font-weight: bold;
|
|
}
|
|
.nav-right {
|
|
display: table-cell;
|
|
width: 100%;
|
|
text-align: right;
|
|
vertical-align: middle;
|
|
line-height: 0;
|
|
}
|
|
.nav-right .share-btn {
|
|
display: none;
|
|
}
|
|
.nav-right .small-share-btn {
|
|
display: none;
|
|
}
|
|
.footer {
|
|
padding-top: 1em;
|
|
border-top: 1px solid #d4d4d4;
|
|
margin-top: 2em;
|
|
color: gray;
|
|
font-size: .9em;
|
|
}
|
|
a.heading-anchor {
|
|
display: inline-block;
|
|
opacity: 0;
|
|
width: 1.3em;
|
|
font-size: 0.7em;
|
|
margin-left: 0.4em;
|
|
line-height: 1em;
|
|
text-decoration: none;
|
|
transition: opacity 0.3s;
|
|
}
|
|
a.heading-anchor:hover,
|
|
h1:hover a.heading-anchor,
|
|
h2:hover a.heading-anchor,
|
|
h3:hover a.heading-anchor,
|
|
h4:hover a.heading-anchor,
|
|
h5:hover a.heading-anchor,
|
|
h6:hover a.heading-anchor {
|
|
opacity: 1;
|
|
}
|
|
|
|
.bottom-links {
|
|
display: flex;
|
|
justify-content: center;
|
|
border-top: 1px solid #d4d4d4;
|
|
margin-top: 30px;
|
|
padding-top: 25px;
|
|
}
|
|
|
|
@media all and (min-width: 400px) {
|
|
.nav-right .share-btn {
|
|
display: inline-block;
|
|
}
|
|
.nav-right .small-share-btn {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="container page-api">
|
|
|
|
<div class="header">
|
|
<a class="forkme" href="https://github.com/laurent22/joplin"><img src="https://joplinapp.org/images/ForkMe.png"/></a>
|
|
<a href="https://joplinapp.org"><h1 class="title"><img class="title-icon" src="https://joplinapp.org/images/Icon512.png"><span class="title-text">Joplin</span></h1></a>
|
|
<p class="sub-title">An open source note taking and to-do application with synchronisation capabilities</p>
|
|
</div>
|
|
|
|
<div class="nav-wrapper">
|
|
<div class="nav">
|
|
<ul>
|
|
<li class=""><a href="https://joplinapp.org/" title="Home"><i class="fa fa-home"></i></a></li>
|
|
<li><a href="https://discourse.joplinapp.org" title="Forum">Forum</a></li>
|
|
<li><a class="help" href="#" title="Menu">Menu</a></li>
|
|
<!-- <li><a class="gsod" href="https://joplinapp.org/gsod2020/" title="Google Season of Docs 2020">GSoD 2020</a></li> -->
|
|
</ul>
|
|
<div class="nav-right">
|
|
<!--
|
|
<iframe class="share-btn" src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplinapp.org&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
|
|
<iframe class="share-btn" src="https://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fjoplinapp.org" width="62" height="20" title="Tweet" style="border: 0; overflow: hidden;"></iframe>
|
|
-->
|
|
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<div id="toc"><ul>
|
|
<li>
|
|
<p>Applications</p>
|
|
<ul>
|
|
<li><a href="https://joplinapp.org/desktop/">Desktop application</a></li>
|
|
<li><a href="https://joplinapp.org/mobile/">Mobile applications</a></li>
|
|
<li><a href="https://joplinapp.org/terminal/">Terminal application</a></li>
|
|
<li><a href="https://joplinapp.org/clipper/">Web Clipper</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Support</p>
|
|
<ul>
|
|
<li><a href="https://discourse.joplinapp.org">Joplin Forum</a></li>
|
|
<li><a href="https://joplinapp.org/markdown/">Markdown Guide</a></li>
|
|
<li><a href="https://joplinapp.org/e2ee/">How to enable end-to-end encryption</a></li>
|
|
<li><a href="https://joplinapp.org/conflict/">What is a conflict?</a></li>
|
|
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
|
<li><a href="https://joplinapp.org/debugging/">How to enable debug mode</a></li>
|
|
<li><a href="https://joplinapp.org/api/">API documentation</a></li>
|
|
<li><a href="https://joplinapp.org/faq/">FAQ</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Google Summer of Code 2020</p>
|
|
<ul>
|
|
<li><a href="https://joplinapp.org/gsoc2020">Google Summer of Code 2020</a></li>
|
|
<li><a href="https://joplinapp.org/gsoc2020/ideas/">Project Ideas</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>About</p>
|
|
<ul>
|
|
<li><a href="https://joplinapp.org/changelog/">Changelog (Desktop App)</a></li>
|
|
<li><a href="https://joplinapp.org/changelog_cli/">Changelog (CLI App)</a></li>
|
|
<li><a href="https://joplinapp.org/stats/">Stats</a></li>
|
|
<li><a href="https://joplinapp.org/donate/">Donate</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<h1>Joplin API<a name="joplin-api" href="#joplin-api" class="heading-anchor">🔗</a></h1>
|
|
<p>In order to use it, you'll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port <strong>41184</strong>. If you want to find it programmatically, you may follow this kind of algorithm:</p>
|
|
<pre><code class="language-javascript">let port = null;
|
|
for (let portToTest = 41184; portToTest <= 41194; portToTest++) {
|
|
const result = pingPort(portToTest); // Call GET /ping
|
|
if (result == 'JoplinClipperServer') {
|
|
port = portToTest; // Found the port
|
|
break;
|
|
}
|
|
}
|
|
</code></pre>
|
|
<h1>Authorisation<a name="authorisation" href="#authorisation" class="heading-anchor">🔗</a></h1>
|
|
<p>To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.</p>
|
|
<p>This would be an example of valid cURL call using a token:</p>
|
|
<pre><code>curl http://localhost:41184/notes?token=ABCD123ABCD123ABCD123ABCD123ABCD123
|
|
</code></pre>
|
|
<p>In the documentation below, the token will not be specified every time however you will need to include it.</p>
|
|
<h1>Using the API<a name="using-the-api" href="#using-the-api" class="heading-anchor">🔗</a></h1>
|
|
<p>All the calls, unless noted otherwise, receives and send <strong>JSON data</strong>. For example to create a new note:</p>
|
|
<pre><code>curl --data '{ "title": "My note", "body": "Some note in **Markdown**"}' http://localhost:41184/notes
|
|
</code></pre>
|
|
<p>In the documentation below, the calls may include special parameters such as :id or :note_id. You would replace this with the item ID or note ID.</p>
|
|
<p>For example, for the endpoint <code>DELETE /tags/:id/notes/:note_id</code>, to remove the tag with ID "ABCD1234" from the note with ID "EFGH789", you would run for example:</p>
|
|
<pre><code>curl -X DELETE http://localhost:41184/tags/ABCD1234/notes/EFGH789
|
|
</code></pre>
|
|
<p>The four verbs supported by the API are the following ones:</p>
|
|
<ul>
|
|
<li><strong>GET</strong>: To retrieve items (notes, notebooks, etc.).</li>
|
|
<li><strong>POST</strong>: To create new items. In general most item properties are optional. If you omit any, a default value will be used.</li>
|
|
<li><strong>PUT</strong>: To update an item. Note in a REST API, traditionally PUT is used to completely replace an item, however in this API it will only replace the properties that are provided. For example if you PUT {"title": "my new title"}, only the "title" property will be changed. The other properties will be left untouched (they won't be cleared nor changed).</li>
|
|
<li><strong>DELETE</strong>: To delete items.</li>
|
|
</ul>
|
|
<h1>Filtering data<a name="filtering-data" href="#filtering-data" class="heading-anchor">🔗</a></h1>
|
|
<p>You can change the fields that will be returned by the API using the <code>fields=</code> query parameter, which takes a list of comma separated fields. For example, to get the longitude and latitude of a note, use this:</p>
|
|
<pre><code>curl http://localhost:41184/notes/ABCD123?fields=longitude,latitude
|
|
</code></pre>
|
|
<p>To get the IDs only of all the tags:</p>
|
|
<pre><code>curl http://localhost:41184/tags?fields=id
|
|
</code></pre>
|
|
<h1>Error handling<a name="error-handling" href="#error-handling" class="heading-anchor">🔗</a></h1>
|
|
<p>In case of an error, an HTTP status code >= 400 will be returned along with a JSON object that provides more info about the error. The JSON object is in the format <code>{ "error": "description of error" }</code>.</p>
|
|
<h1>About the property types<a name="about-the-property-types" href="#about-the-property-types" class="heading-anchor">🔗</a></h1>
|
|
<ul>
|
|
<li>Text is UTF-8.</li>
|
|
<li>All date/time are Unix timestamps in milliseconds.</li>
|
|
<li>Booleans are integer values 0 or 1.</li>
|
|
</ul>
|
|
<h1>Testing if the service is available<a name="testing-if-the-service-is-available" href="#testing-if-the-service-is-available" class="heading-anchor">🔗</a></h1>
|
|
<p>Call <strong>GET /ping</strong> to check if the service is available. It should return "JoplinClipperServer" if it works.</p>
|
|
<h1>Searching<a name="searching" href="#searching" class="heading-anchor">🔗</a></h1>
|
|
<p>Call <strong>GET /search?query=YOUR_QUERY</strong> to search for notes. This end-point supports the <code>field</code> parameter which is recommended to use so that you only get the data that you need. The query syntax is as described in the main documentation: <a href="https://joplinapp.org/#searching">https://joplinapp.org/#searching</a></p>
|
|
<p>To retrieve non-notes items, such as notebooks or tags, add a <code>type</code> parameter and set it to the required <a href="#item-type-id">item type name</a>. In that case, full text search will not be used - instead it will be a simple case-insensitive search. You can also use <code>*</code> as a wildcard. This is convenient for example to retrieve notebooks or tags by title.</p>
|
|
<p>For example, to retrieve the notebook named <code>recipes</code>: <strong>GET /search?query=recipes&type=folder</strong></p>
|
|
<p>To retrieve all the tags that start with <code>project-</code>: <strong>GET /search?query=project-*&type=tag</strong></p>
|
|
<h1>Item type IDs<a name="item-type-ids" href="#item-type-ids" class="heading-anchor">🔗</a></h1>
|
|
<p>Item type IDs might be refered to in certain object you will retrieve from the API. This is the correspondance between name and ID:</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>note</td>
|
|
<td>1</td>
|
|
</tr>
|
|
<tr>
|
|
<td>folder</td>
|
|
<td>2</td>
|
|
</tr>
|
|
<tr>
|
|
<td>setting</td>
|
|
<td>3</td>
|
|
</tr>
|
|
<tr>
|
|
<td>resource</td>
|
|
<td>4</td>
|
|
</tr>
|
|
<tr>
|
|
<td>tag</td>
|
|
<td>5</td>
|
|
</tr>
|
|
<tr>
|
|
<td>note_tag</td>
|
|
<td>6</td>
|
|
</tr>
|
|
<tr>
|
|
<td>search</td>
|
|
<td>7</td>
|
|
</tr>
|
|
<tr>
|
|
<td>alarm</td>
|
|
<td>8</td>
|
|
</tr>
|
|
<tr>
|
|
<td>master_key</td>
|
|
<td>9</td>
|
|
</tr>
|
|
<tr>
|
|
<td>item_change</td>
|
|
<td>10</td>
|
|
</tr>
|
|
<tr>
|
|
<td>note_resource</td>
|
|
<td>11</td>
|
|
</tr>
|
|
<tr>
|
|
<td>resource_local_state</td>
|
|
<td>12</td>
|
|
</tr>
|
|
<tr>
|
|
<td>revision</td>
|
|
<td>13</td>
|
|
</tr>
|
|
<tr>
|
|
<td>migration</td>
|
|
<td>14</td>
|
|
</tr>
|
|
<tr>
|
|
<td>smart_filter</td>
|
|
<td>15</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h1>Notes<a name="notes" href="#notes" class="heading-anchor">🔗</a></h1>
|
|
<h2>Properties<a name="properties" href="#properties" class="heading-anchor">🔗</a></h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>id</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>parent_id</td>
|
|
<td>text</td>
|
|
<td>ID of the notebook that contains this note. Change this ID to move the note to a different notebook.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>title</td>
|
|
<td>text</td>
|
|
<td>The note title.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>body</td>
|
|
<td>text</td>
|
|
<td>The note body, in Markdown. May also contain HTML.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>created_time</td>
|
|
<td>int</td>
|
|
<td>When the note was created.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>updated_time</td>
|
|
<td>int</td>
|
|
<td>When the note was last updated.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_conflict</td>
|
|
<td>int</td>
|
|
<td>Tells whether the note is a conflict or not.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>latitude</td>
|
|
<td>numeric</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>longitude</td>
|
|
<td>numeric</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>altitude</td>
|
|
<td>numeric</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>author</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>source_url</td>
|
|
<td>text</td>
|
|
<td>The full URL where the note comes from.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_todo</td>
|
|
<td>int</td>
|
|
<td>Tells whether this note is a todo or not.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>todo_due</td>
|
|
<td>int</td>
|
|
<td>When the todo is due. An alarm will be triggered on that date.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>todo_completed</td>
|
|
<td>int</td>
|
|
<td>Tells whether todo is completed or not. This is a timestamp in milliseconds.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>source</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>source_application</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>application_data</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>order</td>
|
|
<td>numeric</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_created_time</td>
|
|
<td>int</td>
|
|
<td>When the note was created. It may differ from created_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_updated_time</td>
|
|
<td>int</td>
|
|
<td>When the note was last updated. It may differ from updated_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_cipher_text</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_applied</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>markup_language</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_shared</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>body_html</td>
|
|
<td>text</td>
|
|
<td>Note body, in HTML format</td>
|
|
</tr>
|
|
<tr>
|
|
<td>base_url</td>
|
|
<td>text</td>
|
|
<td>If <code>body_html</code> is provided and contains relative URLs, provide the <code>base_url</code> parameter too so that all the URLs can be converted to absolute ones. The base URL is basically where the HTML was fetched from, minus the query (everything after the '?'). For example if the original page was <code>https://stackoverflow.com/search?q=%5Bjava%5D+test</code>, the base URL is <code>https://stackoverflow.com/search</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>image_data_url</td>
|
|
<td>text</td>
|
|
<td>An image to attach to the note, in <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs">Data URL</a> format.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>crop_rect</td>
|
|
<td>text</td>
|
|
<td>If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format <code>{ x: x, y: y, width: width, height: height }</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2>GET /notes<a name="get-notes" href="#get-notes" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all notes</p>
|
|
<h2>GET /notes/:id<a name="get-notes-id" href="#get-notes-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets note with ID :id</p>
|
|
<h2>GET /notes/:id/tags<a name="get-notes-id-tags" href="#get-notes-id-tags" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all the tags attached to this note.</p>
|
|
<h2>GET /notes/:id/resources<a name="get-notes-id-resources" href="#get-notes-id-resources" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all the resources attached to this note.</p>
|
|
<h2>POST /notes<a name="post-notes" href="#post-notes" class="heading-anchor">🔗</a></h2>
|
|
<p>Creates a new note</p>
|
|
<p>You can either specify the note body as Markdown by setting the <code>body</code> parameter, or in HTML by setting the <code>body_html</code>.</p>
|
|
<p>Examples:</p>
|
|
<ul>
|
|
<li>
|
|
<p>Create a note from some Markdown text</p>
|
|
<pre><code>curl --data '{ "title": "My note", "body": "Some note in **Markdown**"}' http://127.0.0.1:41184/notes
|
|
</code></pre>
|
|
</li>
|
|
<li>
|
|
<p>Create a note from some HTML</p>
|
|
<pre><code>curl --data '{ "title": "My note", "body_html": "Some note in <b>HTML</b>"}' http://127.0.0.1:41184/notes
|
|
</code></pre>
|
|
</li>
|
|
<li>
|
|
<p>Create a note and attach an image to it:</p>
|
|
<pre><code>curl --data '{ "title": "Image test", "body": "Here is Joplin icon:", "image_data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="}' http://127.0.0.1:41184/notes
|
|
</code></pre>
|
|
</li>
|
|
</ul>
|
|
<h3>Creating a note with a specific ID<a name="creating-a-note-with-a-specific-id" href="#creating-a-note-with-a-specific-id" class="heading-anchor">🔗</a></h3>
|
|
<p>When a new note is created, it is automatically assigned a new unique ID so <strong>normally you do not need to set the ID</strong>. However, if for some reason you want to set it, you can supply it as the <code>id</code> property. It needs to be a <strong>32 characters long string</strong> in hexadecimal. <strong>Make sure it is unique</strong>, for example by generating it using whatever GUID function is available in your programming language.</p>
|
|
<pre><code> curl --data '{ "id": "00a87474082744c1a8515da6aa5792d2", "title": "My note with custom ID"}' http://127.0.0.1:41184/notes
|
|
</code></pre>
|
|
<h2>PUT /notes/:id<a name="put-notes-id" href="#put-notes-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Sets the properties of the note with ID :id</p>
|
|
<h2>DELETE /notes/:id<a name="delete-notes-id" href="#delete-notes-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Deletes the note with ID :id</p>
|
|
<h1>Folders<a name="folders" href="#folders" class="heading-anchor">🔗</a></h1>
|
|
<p>This is actually a notebook. Internally notebooks are called "folders".</p>
|
|
<h2>Properties<a name="properties-1" href="#properties-1" class="heading-anchor">🔗</a></h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>id</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>title</td>
|
|
<td>text</td>
|
|
<td>The folder title.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>created_time</td>
|
|
<td>int</td>
|
|
<td>When the folder was created.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>updated_time</td>
|
|
<td>int</td>
|
|
<td>When the folder was last updated.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_created_time</td>
|
|
<td>int</td>
|
|
<td>When the folder was created. It may differ from created_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_updated_time</td>
|
|
<td>int</td>
|
|
<td>When the folder was last updated. It may differ from updated_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_cipher_text</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_applied</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>parent_id</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_shared</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2>GET /folders<a name="get-folders" href="#get-folders" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all folders</p>
|
|
<p>The folders are returned as a tree. The sub-notebooks of a notebook, if any, are under the <code>children</code> key.</p>
|
|
<h2>GET /folders/:id<a name="get-folders-id" href="#get-folders-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets folder with ID :id</p>
|
|
<h2>GET /folders/:id/notes<a name="get-folders-id-notes" href="#get-folders-id-notes" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all the notes inside this folder.</p>
|
|
<h2>POST /folders<a name="post-folders" href="#post-folders" class="heading-anchor">🔗</a></h2>
|
|
<p>Creates a new folder</p>
|
|
<h2>PUT /folders/:id<a name="put-folders-id" href="#put-folders-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Sets the properties of the folder with ID :id</p>
|
|
<h2>DELETE /folders/:id<a name="delete-folders-id" href="#delete-folders-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Deletes the folder with ID :id</p>
|
|
<h1>Resources<a name="resources" href="#resources" class="heading-anchor">🔗</a></h1>
|
|
<h2>Properties<a name="properties-2" href="#properties-2" class="heading-anchor">🔗</a></h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>id</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>title</td>
|
|
<td>text</td>
|
|
<td>The resource title.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>mime</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>filename</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>created_time</td>
|
|
<td>int</td>
|
|
<td>When the resource was created.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>updated_time</td>
|
|
<td>int</td>
|
|
<td>When the resource was last updated.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_created_time</td>
|
|
<td>int</td>
|
|
<td>When the resource was created. It may differ from created_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_updated_time</td>
|
|
<td>int</td>
|
|
<td>When the resource was last updated. It may differ from updated_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>file_extension</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_cipher_text</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_applied</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_blob_encrypted</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>size</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_shared</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2>GET /resources<a name="get-resources" href="#get-resources" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all resources</p>
|
|
<h2>GET /resources/:id<a name="get-resources-id" href="#get-resources-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets resource with ID :id</p>
|
|
<h2>GET /resources/:id/file<a name="get-resources-id-file" href="#get-resources-id-file" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets the actual file associated with this resource.</p>
|
|
<h2>POST /resources<a name="post-resources" href="#post-resources" class="heading-anchor">🔗</a></h2>
|
|
<p>Creates a new resource</p>
|
|
<p>Creating a new resource is special because you also need to upload the file. Unlike other API calls, this one must have the "multipart/form-data" Content-Type. The file data must be passed to the "data" form field, and the other properties to the "props" form field. An example of a valid call with cURL would be:</p>
|
|
<pre><code>curl -F 'data=@/path/to/file.jpg' -F 'props={"title":"my resource title"}' http://localhost:41184/resources
|
|
</code></pre>
|
|
<p>The "data" field is required, while the "props" one is not. If not specified, default values will be used.</p>
|
|
<h2>PUT /resources/:id<a name="put-resources-id" href="#put-resources-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Sets the properties of the resource with ID :id</p>
|
|
<h2>DELETE /resources/:id<a name="delete-resources-id" href="#delete-resources-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Deletes the resource with ID :id</p>
|
|
<h1>Tags<a name="tags" href="#tags" class="heading-anchor">🔗</a></h1>
|
|
<h2>Properties<a name="properties-3" href="#properties-3" class="heading-anchor">🔗</a></h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>id</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>title</td>
|
|
<td>text</td>
|
|
<td>The tag title.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>created_time</td>
|
|
<td>int</td>
|
|
<td>When the tag was created.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>updated_time</td>
|
|
<td>int</td>
|
|
<td>When the tag was last updated.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_created_time</td>
|
|
<td>int</td>
|
|
<td>When the tag was created. It may differ from created_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>user_updated_time</td>
|
|
<td>int</td>
|
|
<td>When the tag was last updated. It may differ from updated_time as it can be manually set by the user.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_cipher_text</td>
|
|
<td>text</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>encryption_applied</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td>is_shared</td>
|
|
<td>int</td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<h2>GET /tags<a name="get-tags" href="#get-tags" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all tags</p>
|
|
<h2>GET /tags/:id<a name="get-tags-id" href="#get-tags-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets tag with ID :id</p>
|
|
<h2>GET /tags/:id/notes<a name="get-tags-id-notes" href="#get-tags-id-notes" class="heading-anchor">🔗</a></h2>
|
|
<p>Gets all the notes with this tag.</p>
|
|
<h2>POST /tags<a name="post-tags" href="#post-tags" class="heading-anchor">🔗</a></h2>
|
|
<p>Creates a new tag</p>
|
|
<h2>POST /tags/:id/notes<a name="post-tags-id-notes" href="#post-tags-id-notes" class="heading-anchor">🔗</a></h2>
|
|
<p>Post a note to this endpoint to add the tag to the note. The note data must at least contain an ID property (all other properties will be ignored).</p>
|
|
<h2>PUT /tags/:id<a name="put-tags-id" href="#put-tags-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Sets the properties of the tag with ID :id</p>
|
|
<h2>DELETE /tags/:id<a name="delete-tags-id" href="#delete-tags-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Deletes the tag with ID :id</p>
|
|
<h2>DELETE /tags/:id/notes/:note_id<a name="delete-tags-id-notes-note-id" href="#delete-tags-id-notes-note-id" class="heading-anchor">🔗</a></h2>
|
|
<p>Remove the tag from the note.</p>
|
|
|
|
<div class="bottom-links">
|
|
<a href="https://github.com/laurent22/joplin/blob/master/readme/api.md">
|
|
<i class="fa fa-github"></i> Improve this doc
|
|
</a>
|
|
</div>
|
|
<script>
|
|
function stickyHeader() {
|
|
return; // Disabled
|
|
|
|
if ($(window).scrollTop() > 179) {
|
|
$('.nav').addClass('sticky');
|
|
} else {
|
|
$('.nav').removeClass('sticky');
|
|
}
|
|
}
|
|
|
|
$('#toc').hide();
|
|
|
|
$('.help').click(function(event) {
|
|
event.preventDefault();
|
|
$('#toc').show();
|
|
});
|
|
|
|
$(window).scroll(function() {
|
|
stickyHeader();
|
|
});
|
|
|
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
ga('create', 'UA-103586105-1', 'auto');
|
|
ga('send', 'pageview');
|
|
</script>
|
|
|
|
<div class="footer">
|
|
Copyright (c) 2016-2020 Laurent Cozic
|
|
</div>
|
|
</body>
|
|
</html>
|