Welcome to the Magnet API Docs

Intro

This API speaks JSON. That is to say it only accepts and returns data with the Content-Type of application/json. So set your headers appropriately.

As such, all data that you POST or PUT to the API should be valid JSON:

For example, a POST to the /articles endpoint might look something like this:

Headers
Content-Type → application/json
Authorization → method=dropbox, token=123456789
{
  "title": "Test Article",
  "keywords": ["this", "is" "just", "a", "test"],
  "scheduled": true,
  "scheduledDate": "2016-12-10T21:15:07.271084+00:00"
}

On GET, if a field doesn't have data, rather than returning an undefined or null value, it will return as an empty entry of that type (ie. an empty "" for the type <string>, [] for <list>).

Authorizing your requests

Make sure that you have the following handy before you begin:

All requests to the API must be authorized before any data will be returned. This is accomplished by sending your auth information in the Authorization header of your request.

There are currently two approved methods of authentication. One is via a read only API key and the other is through Dropbox.

However, no matter what form of authorization you choose/need, and no matter what new forms of authorization are eventually added, the format remains the same:

Examples

Headers
Authorization → method=dropbox, token=123456789ABCDE
Authorization → method=apikey, token=ABCDE123456789

Any error with authentication will result in a 401 error. The response body will contain a JSON response with more detail regarding the error.

Endpoints

/articles

methods GET, POST, OPTIONS, HEAD

Responds with a paginated list of articles.

/articles/:id

methods GET, PUT, DELETE, OPTIONS, HEAD

Responds with a single article.

/articles/:key/:value

methods GET, OPTIONS, HEAD

Responds with a paginated list of articles with a given value for a given key.

/articles/drafts

methods GET, OPTIONS, HEAD

Responds with a paginated list of drafted articles (ie. unpublished).

/articles/keyword/:keyword

methods GET, OPTIONS, HEAD

Responds with a paginated list of articles with a given keyword.

/articles/published

methods GET, OPTIONS, HEAD

Responds with a paginated list of published articles.

/articles/published/since/:datestamp

methods GET, OPTIONS, HEAD

Responds with published articles changed since the ISO 8601 date in the URL.

/articles/scheduled

methods GET, OPTIONS, HEAD

Responds with a paginated list of scheduled articles.

/articles/since/:datestamp

methods GET, OPTIONS, HEAD

Responds with a paginated list of articles changed since the ISO 8601 date in the URL.

/fields

methods GET, POST, OPTIONS, HEAD

Responds with a paginated list of custom fields.

/fields/:collection

methods GET, OPTIONS, HEAD

For fetching the fields associated with a collection

/fields/:id

methods GET, PUT, DELETE, OPTIONS, HEAD

Responds with a single field.

/issues

methods GET, POST, OPTIONS, HEAD

Responds with a paginated list of issues.

/issues/:id

methods GET, PUT, DELETE, OPTIONS, HEAD

Responds with a single issue.

/issues/:key/:value

methods GET, OPTIONS, HEAD

Responds with a paginated list of issues with a given value for a given key.

/issues/drafts

methods GET, OPTIONS, HEAD

Responds with a paginated list of drafted issues.

/issues/preview

methods GET, OPTIONS, HEAD

Responds with a paginated list of issues in preview state.

/issues/published

methods GET, OPTIONS, HEAD

Responds with a paginated list of published issues.

/issues/published/since/:datestamp

methods GET, OPTIONS, HEAD

Responds with published issues changed since the ISO 8601 datestamp in the URL.

/issues/scheduled

methods GET, OPTIONS, HEAD

Responds with a paginated list of scheduled issues.

/media

methods GET, POST, OPTIONS, HEAD

Responds with a paginated list of media.

/media/:id

methods GET, PUT, DELETE, OPTIONS, HEAD

Responds with a single piece of media

/media/:key/:value

methods GET, OPTIONS, HEAD

Responds with a paginated list of media with a given value for a given key.

/volumes

methods GET, POST, OPTIONS, HEAD

Responds with a paginated list of volumes.

/volumes/:id

methods GET, PUT, DELETE, OPTIONS, HEAD

Responds with a single volume.

/volumes/:key/:value

methods GET, OPTIONS, HEAD

Responds with a paginated list of volumes with a given value for a given key.

Types

When posting to the API, the body will be a JSON object with the usual JSON types:

However, some of the fields require specific kinds of data. These fields are:

// POST to /issues

{
  "articles": ["1a2ba3c4d5e", "6f7g8h9i1j"]
}
// POST to /articles

{
  "sechduled": true,
  "scheduledDate": "2015-10-04T20:33:14.345Z"
}
// POST to /media

{
  "upload": true,
  "file": "iVBORw0KGgoAAAANSUhEUgAAAjkAAAOCCAIAAAAa81Q4AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAA6ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx..."
}

Default Fields

Requesting data

By default, certain fields are restricted when you make a GET request to a collection endpoint (eg. /articles,/issues,/media, etc.). Often this is to reduce the size of the response for the sake of performance. Also, requests are limited to 10 entries per page.

However, to advance the page or request a larger amount of data, or display restricted fields, you can use several query parameters to manipulate the data. Available query parameters are as follows:

Examples:

Custom Fields

If you note in the examples of GET requests in "Default Fields" section, there is an empty object called customMeta. Any custom field declared in /fields for a particular collection will be listed in the customMeta object.

In order to demonstrate these custom fields, let's see an example work flow where we create a custom field, POST data to it, and then retrieve it on GET.

Creating a field

When creating a new field, the most crucial pieces of data are the collection and the type.

The collection should be the collection where you want to use the field: articles, authors, issues, fields, or media.

The type should be a valid JSON data type (excluding objects): string, list, or boolean.

So as an example, let's create a custom field for issues called "issueVolAndNumber" that will be used to store the volume number and issue number. In this case, we'll use a string, and there won't be any defaultData and the default is an empty string.

"POST to /fields"
{
  "collection": "issues",
  "default": "",
  "defaultData": [],
  "description": "The volume number and issue number",
  "title": "issueVolAndNumber",
  "type": "string"
}

As another example, we'll create a custom field for articles. This field will be called "genre" for our fictional publication Fiction and Poetry. This magazine only publishes fiction articles and poetry articles. So they want to limit the number of choices. In this case, we'll be using a string again but add defaultData and a default of empty string.

"POST to /fields"
{
  "collection": "articles",
  "default": "",
  "defaultData": ["fiction", "poetry"],
  "description": "The article genre",
  "title": "genre",
  "type": "string"
}

Posting with a custom field

Using our first example "issueVolAndNumber", let's see what a POST to /issues might look like.

"POST to /issues"
{
    "articles": ["12345678", "23456789", "34567890"],
    "coverPhone": "0987654",
    "coverTablet": "9876543",
    "coverTabletLandscape": "8765432",
    "description": "The best issue you've ever read about fruit.",
    "displayDate": "Oct 2015",
    "featured": false,
    "isFree": false,
    "media": ["0987654", "9876543", "8765432"],
    "published": false,
    "pushNotification": "Read the issue now!",
    "scheduled": true,
    "scheduledDate": "2015-10-04T20:33:14.345Z",
    "subtitle": "and other fruits",
    "title": "Bananas",
    "issueVolAndNumber": "Vol. 11 Issue 23"
}

"issueVolAndNumber" is POSTed along with all of the other values in a flat JSON object.

Getting a custom field

If we were to retrieve that issue, Bananas: and other fruits what might the response look like with the custom field?

"GET from /issues/8299948746"
{
"issues": [{
    "articles": [
      {
        "id": "12345678", 
        "title": "Letter From the Editor"
        "authors": [
          {"name": "Duncan Regan", "id": "46574893"}
        ]
      },
      {
        "id": "23456789",
        "title": "Bananas"
        "authors": [
          {"name": "Duncan Regan", "id": "46574893"}
        ]
      },
      {
        "id": "34567890",
        "title": "Apples and Other Fruits"
        "authors": [
          {"name": "Nora Bearman", "id": "89294775"}
        ]
      }
    ],
    "clientId": "2343556",
    "coverPhone": "0987654",
    "coverTablet": "9876543",
    "coverTabletLandscape": "8765432",
    "customMeta": {
      "issueVolAndNumber": "Vol. 11 Issue 23"
    },
    "description": "The best issue you've ever read about fruit.",
    "featured": false,
    "id": "8299948746",
    "media": [
      {"id": "0987654", "title": "banana_cover"},
      {"id": "9876543", "title": "banana_cover2"},
      {"id": "8765432", "title": "banana_cover3"}
    ],
    "meta": {
        "created": "2015-01-15T22:51:55.455Z",
        "displayDate": "Oct 2015>",
        "isFree": false,
        "published": false,
        "publishedDate": "",
        "scheduled": true,
        "scheduledDate": "2015-10-04T20:33:14.345Z",
        "updated": {
            "date": "2015-01-15T23:32:12.455Z",
            "updatedBy": "duncan@29.io"
        }
    },
    "pushNotification": "Read the issue now!",
    "subtitle": "and other fruits",
    "title": "Bananas"
}]
}

There in customMeta is our custom field issueVolAndNumber:

"customMeta": {
  "issueVolAndNumber": "Vol. 11 Issue 23"
}

Accessing the property is as easy as

issues[0].customMeta.issueVolAndNumber