diff --git a/package.json b/package.json index 22f42910..1a062f37 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "NODE_ENV=production webpack --config webpack.config.prod.js --json | webpack-bundle-size-analyzer", "build": "npm run clean && npm run build:webpack", "start": "NODE_ENV=production node index.js", - "dev": "NODE_ENV=development nodemon --inspect --watch server index.js", + "dev": "NODE_ENV=development nodemon --watch server index.js", "lint": "npm run lint:flow && npm run lint:js", "lint:js": "eslint app", "lint:flow": "flow", diff --git a/server/pages/Api.js b/server/pages/Api.js new file mode 100644 index 00000000..f5b580e0 --- /dev/null +++ b/server/pages/Api.js @@ -0,0 +1,200 @@ +// @flow +import React from 'react'; +import Grid from 'styled-components-grid'; +import { Helmet } from 'react-helmet'; +import Flex from '../../shared/components/Flex'; + +export default function Pricing() { + return ( + + + Developer API + +
+

Outline API

+

+ First thing we build for Outline was its API. It's the heart and sole of the service and + as developers, it's our mission to make the API as rich and easy to use as possible. +

+

+ + While Outline is still in public beta, we might make small adjustments, including + breaking changes to the API. + +

+

Making requests

+

+ Outline's API follows simple RPC style conventions where each API endpoint is a method on{' '} + https://www.getoutline.com/api/<METHOD>. Both GET and{' '} + POST methods are supported but it's recommeded that you make all call using{' '} + POST. Only HTTPS is supported in production. +

+ +

+ For GET requests query string parameters are expected (e.g. + /api/document.info?id=...&token=...). When making POST requests, + request parameters are parsed depending on Content-Type header. To make a + call using JSON payload, one must pass Content-Type: application/json header: +

+ +

+ Example POST request: +

+
+          
+            {`
+curl https://www.getoutline.com/api/documents.info
+  -X POST
+  -H 'authorization: Bearer API_KEY'
+  -H 'content-type: application/json'
+  -H 'accept: application/json'
+  -d '{"id": "outline-api-NTpezNwhUP"}'
+`}
+          
+        
+ +

+ Example GET request: +

+
+          
+            {`
+curl https://www.getoutline.com/api/documents.info?id=outline-api-NTpezNwhUP&token=API_KEY
+`}
+          
+        
+ +

Authentication

+ +

+ To access private API endpoints, you must provide a valid API key. You can create new API + keys in your account settings. Be careful when + handling your keys as they give access to all of your documents. +

+ +

+ To authenticate with Outline API, you can supply the API key as a header ( + Authorization: Bearer YOUR_API_KEY + ) or as part of the payload using token parameter. If you're making{' '} + GET requests, header based authentication is recommended so that your keys + don't leak into logs. +

+ +

+ Some API endpoints allow unauhenticated requests for public resources and they can be + called without an API key. +

+ +

Errors

+ +

+ All successful API requests will be returned with 200 status code and{' '} + ok: true in the response payload. If there's an error while making the + request, appropriate status code is returned with the error message: +

+ +
+          
+            {`
+{
+  "ok": false,
+  "error: "Not Found"
+}
+`}
+          
+        
+ +

Methods

+ + + + This method returns the information for currently logged in user. + + + + + + + + + You can upload small files and images as part of your documents. All files are stored + using Amazon S3. Instead of uploading files to Outline, you need to upload them directly + to S3 with special credentials which can be obtained through this endpoint. + + + + + + + + + + List all your document collections. + + + + + Returns detailed information on a document collection. + + + + +
+
+ ); +} + +type MethodProps = { + method: string, + label: string, + children: React.Element<*>, +}; + +const Method = (props: MethodProps) => { + const children = React.Children.toArray(props.children); + const description = children.find(child => child.type === Description); + const apiArgs = children.find(child => child.type === Arguments); + + return ( +
+

+ {props.method} - {props.label} +

+
{description}
+

Arguments

+

+ {`${process.env.URL}/api/${props.method}`} +

+ {apiArgs} +
+ ); +}; + +const Description = (props: { children: React.Element<*> }) =>

{props.children}

; +const Arguments = (props: { children: React.Element<*> }) => ( + + + + + + + + + + + {props.pagination && } + {props.children} + +
ArgumentRequiredDescription
+); +const Argument = (props: { children: React.Element<*> }) => ( + + {props.id} + {props.required ? 'required' : 'optional'} + {props.description} + +); +const PaginationArguments = () => [ + , + , +]; diff --git a/server/routes.js b/server/routes.js index 3edbf4be..b96ff7d1 100644 --- a/server/routes.js +++ b/server/routes.js @@ -12,6 +12,7 @@ import renderpage from './utils/renderpage'; import Home from './pages/Home'; import About from './pages/About'; import Pricing from './pages/Pricing'; +import Api from './pages/Api'; const isProduction = process.env.NODE_ENV === 'production'; const koa = new Koa(); @@ -46,6 +47,7 @@ if (process.env.NODE_ENV === 'production') { // static pages router.get('/about', ctx => renderpage(ctx, )); router.get('/pricing', ctx => renderpage(ctx, )); +router.get('/developers', ctx => renderpage(ctx, )); // home page router.get('/', async ctx => {