# Overview

The Memento Yearbook Publisher API is organized around REST - it returns JSON encoded responses and uses standard HTTP response codes.

# Authentication

The Publisher API uses access tokens to authenticate requests.

To use the API, visit the Access Token Dashboard (opens new window) and generate an access token.

TIP

Treat your access token like an account password. Anyone with this token can perform actions based upon your publisher account.

# Authentication example

To authenticate a request, include your access token in the Authorization header of your request.

import axios from 'axios'

// #todo - update this token with the one generated from your publisher dashboard
const token = 'gUYq8baOoGKRv0zj2QuOVJ62U6ITVf1z5mSc0WGM';
const client = axios.create({
  baseURL: 'https://yearbooks.me/api/external/publishers/v1',
  headers: {
    Authorization: `Bearer ${token}`,
    Accept: 'application/json'
  }
})

# Checking the response

The publisher API returns standard HTTP response codes. Anything within the 2xx range can be considered successful. Codes within the 4xx range indicate an error related to the information given (e.g. missing a required parameter, unauthorized). Codes in the 5xx range generally indicate an internal server error.

When querying an API resource, a typical response will include a JSON-encoded object with the following properties:

{
  "data": {
    "type": "proof",
    "id": "7c93d668-7a9f-11ea-8bc2-fa163ec9614d",
    "attributes": {
      // omitted
    }
  },
  // the status code of the response 
  "meta": {
    "code": 200
  }
}

# Validating responses

The following Javascript example shows how to make an authenticated request to the API and parse the response:

import axios from 'axios';
import { get } from 'lodash';

// use the token generated from the publisher dashboard
const token = 'gUYq8baOoGKRv0zj2QuOVJ62U6ITVf1z5mSc0WGM';
const client = axios.create({
  baseURL: 'https://yearbooks.me/api/external/publishers/v1',
  headers: {
    Authorization: `Bearer ${token}`,
    Accept: 'application/json'
  },
});

export async function getProof(id) {
  try {
    const response = await client.get(`proof/${id}`);
    // successful response (status code is within `2xx` range)
    return response.data || apiData;
  } catch (error) {
    // most API errors within the 4xx range will include 
    // a meta property with an error description
    // if this isn't set, typically this will be a server error (5xx) or a networking issue 
    const errorReport = get(error, 'response.data.meta') || get(error, 'response.data') || error;
    console.error(`*** error occurred ***`);
    console.log(errorReport);
    throw new Error(error);
}
}

If a request fails in the 4xx range, you can expect some feedback given in the meta property of the response:

{
  "meta": {
    "message": "Publisher can only cancel a proof if it has been approved",
    "code": 422
  }
}

# Proofing API

# Get Proof

GET proof/{id}

This API returns information about a proof.

Required params:

  • id
    • description: the id of the proof

Response (200):

{
  "data": {
    "type": "proof",
    "id": "0c32e0fc-1faa-11eb-81c4-080027d0ed3e",
    "attributes": {
        "book_id": "012343fc-96e6-11ea-918e-fa163ec9614d",
        "book_name": "Test Yearbook",
        "book_due_date": "2021-05-17T02:01:52Z",
        "book_editor_in_chief_email" => "johndoe@example.com",
        "book_type_name": "8.5 x 11 Softcover",
        "book_type_id": "8963a32e-b271-11e9-855d-fa163ec9614d",
        "book_form_factor": {
              "maxDefaultPages": 100,
              "minDefaultPages": 20,
              "name": "8.5 x 11 Softcover",
              "outputSettings": {
                "dpi": 300,
                "dpiError": 100,
                "dpiWarning": 150,
                "outputType": "pdf",
                "pdfOutput": "oneFileForBookAndCover",
                "splitCover": "none"
              },
              "pageStarting": "right",
              "pageTypes": {
                "cover": {
                  "bleed": {
                    "bottom": 0.15,
                    "left": 0.15,
                    "right": 0.15,
                    "top": 0.15
                  },
                  "cover": {
                    "backFlap": 0,
                    "frontFlap": 0,
                    "orientation": "vertical",
                    "spine": 0.75
                  },
                  "margins": {
                    "bottom": 0.5,
                    "left": 0.5,
                    "right": 0.5,
                    "top": 0.5
                  },
                  "pageHeight": 12.7,
                  "pageType": "cover",
                  "pageWidth": 19.9,
                  "safeZone": {
                    "bottom": 0.25,
                    "left": 0.25,
                    "right": 0.25,
                    "top": 0.25
                  },
                  "unit": "inch"
                },
                "single": {
                  "bleed": {
                    "bottom": 0.15,
                    "left": 0.15,
                    "right": 0.15,
                    "top": 0.15
                  },
                  "margins": {
                    "bottom": 0.5,
                    "left": 0.5,
                    "right": 0.5,
                    "top": 0.5
                  },
                  "pageHeight": 11,
                  "pageType": "single",
                  "pageWidth": 8.5,
                  "safeZone": {
                    "bottom": 0.25,
                    "left": 0.25,
                    "right": 0.25,
                    "top": 0.25
                  },
                  "unit": "inch"
                }
              },
              "sku": "BOOK_YB_001",
              "totalPagesMultipleOf": 0,
              "type": "book",
              "version": 1
        },
        "cover_due_date": "2021-05-17T02:01:52Z",
        "created_at": "2020-11-16T02:01:52Z",
        "created_by_user_id": 1,
        "created_by_display_name": "Test editor-in-chief",
        "final_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/book.zip",
        "final_pdf_url_expires_at": "2021-02-15T02:01:52Z",
        "final_flattened_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/flattened_book.zip",
        "final_flattened_pdf_url_expires_at": "2021-02-15T02:01:52Z",
        "publisher_approved_at": "2020-11-16T02:01:52Z",
        "proof_cancelled_at": null,
        "proof_cancelled_comment": null,
        "proof_id": "0c32e0fc-1faa-11eb-81c4-080027d0ed3e",
        "status": "APPROVED",
        "school_id": 1,
        "school_name": "Test School",
        "type": "book",
        "version": 3,
        "watermarked_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/book_wm.pdf"
    }
  },
  "meta": {
    "code": 200
  }
}

This API may return 422 (not found) or 403 (forbidden).

# Cancel Proof

POST proof/{id}/cancel

This API cancels a proof which was submitted. Typically, you would only call this API if you are using your own proofing system.

Required params:

  • id
    • description: the id of the proof
  • comment: the reason why the proof is being cancelled (this comment is shared with the school)
    • rules:
      • string|max:255

Response (200):

{
  "data": {
    "type": "proof",
    "id": "0c32e0fc-1faa-11eb-81c4-080027d0ed3e",
    "attributes": {
        "book_id": "012343fc-96e6-11ea-918e-fa163ec9614d",
        "book_name": "Test Yearbook",
        "book_due_date": "2021-05-17T02:01:52Z",
        "book_editor_in_chief_email": "johndoe@example.com",
        "book_type_name": "8.5 x 11 Softcover",
        "book_type_id": "8963a32e-b271-11e9-855d-fa163ec9614d",
        "book_form_factor": {
              "maxDefaultPages": 100,
              "minDefaultPages": 20,
              "name": "8.5 x 11 Softcover",
              "outputSettings": {
                "dpi": 300,
                "dpiError": 100,
                "dpiWarning": 150,
                "outputType": "pdf",
                "pdfOutput": "oneFileForBookAndCover",
                "splitCover": "none"
              },
              "pageStarting": "right",
              "pageTypes": {
                "cover": {
                  "bleed": {
                    "bottom": 0.15,
                    "left": 0.15,
                    "right": 0.15,
                    "top": 0.15
                  },
                  "cover": {
                    "backFlap": 0,
                    "frontFlap": 0,
                    "orientation": "vertical",
                    "spine": 0.75
                  },
                  "margins": {
                    "bottom": 0.5,
                    "left": 0.5,
                    "right": 0.5,
                    "top": 0.5
                  },
                  "pageHeight": 12.7,
                  "pageType": "cover",
                  "pageWidth": 19.9,
                  "safeZone": {
                    "bottom": 0.25,
                    "left": 0.25,
                    "right": 0.25,
                    "top": 0.25
                  },
                  "unit": "inch"
                },
                "single": {
                  "bleed": {
                    "bottom": 0.15,
                    "left": 0.15,
                    "right": 0.15,
                    "top": 0.15
                  },
                  "margins": {
                    "bottom": 0.5,
                    "left": 0.5,
                    "right": 0.5,
                    "top": 0.5
                  },
                  "pageHeight": 11,
                  "pageType": "single",
                  "pageWidth": 8.5,
                  "safeZone": {
                    "bottom": 0.25,
                    "left": 0.25,
                    "right": 0.25,
                    "top": 0.25
                  },
                  "unit": "inch"
                }
              },
              "sku": "BOOK_YB_001",
              "totalPagesMultipleOf": 0,
              "type": "book",
              "version": 1
            },
        "cover_due_date": "2021-05-17T02:01:52Z",
        "created_at": "2020-11-16T02:01:52Z",
        "created_by_user_id": 1,
        "created_by_display_name": "Test editor-in-chief",
        "final_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/book.zip",
        "final_pdf_url_expires_at": "2021-02-15T02:01:52Z",
        "final_flattened_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/flattened_book.zip",
        "final_flattened_pdf_url_expires_at": "2021-02-15T02:01:52Z",
        "publisher_approved_at": "2020-11-16T02:01:52Z",
        "proof_cancelled_at": '2020-11-25T02:01:52Z',
        "proof_cancelled_comment": 'Spelling mistake on the cover page',
        "proof_id": "0c32e0fc-1faa-11eb-81c4-080027d0ed3e",
        "status": 'REJECTED',
        "school_id": 1,
        "school_name": "Test School",
        "type": "book",
        "version": 3,
        "watermarked_pdf_url": "https://s3.amazonaws.com/mementoyearbook.s3.mementopix.com/book_wm.pdf"
    }
  },
  "meta": {
    "code": 200
  }
}

This API may return 422 (not found, proof cancellation not allowed) or 403 (forbidden).

TIP

This API will only allow a proof to be cancelled if its state is APPROVED (submitted to the publisher). Trying to cancel a proof in any other state will return a 422 error.

# School API

# Get Schools

GET schools

This API returns an array of all of your schools - including the books that belong to them.

Response (200)

{
  "data": [
    {
      "type": "school",
      "id": "1",
      "attributes": {
        "active": true,
        "address": {
          "address_1": "Fake address line 1",
          "address_2": "Fake address line 2",
          "city": "Fake city",
          "zipcode": "91300",
          "country": "United States",
          "country_code": "US",
          "state": "CA",
          "province": null
        },
        "book_count": 1,
        "books": [
          {
            "id": "2581ca9a-4336-11ec-8128-080027d0ed3e",
            "admin_email": "nakedgun@gmail.com",
            "admin_first_name": "Test",
            "admin_last_name": "Editor-in-Chief",
            "book_due_date": "2022-07-11T00:00:00Z",
			"book_fixed_page_count": null,
            "book_type_id": "250c0a4e-4336-11ec-9d16-080027d0ed3e",
            "book_type_name": "8.5 x 11 Softcover",
            "book_invitation_email_status": "Not sent",
            "cover_due_date": "2022-02-11T00:00:00Z",
            "child_privacy_laws_applicable": false,
            "created_at": "2021-11-11T21:27:17Z",
            "form_factor_id": "600e93ab-9ac2-4732-81a2-97b90562b519",
            "is_setup": false,
            "license_valid": true,
            "license_expires_at": "2022-11-11 21:27:17",
            "name": "Acme School Yearbook",
            "users": [
              "mementopix",
              "editor-in-chief@acmeschool.com",
              "editor@acmeschool.com",
              "staffer@acmeschool.com"
            ],
            "storefront_id": "27ec2f3c-4336-11ec-a896-080027d0ed3e"
          }
        ],
        "config": {
          "help": {
            "setting_use_custom_help_system": false,
            "setting_help_knowledge_base_url": null,
            "setting_help_ticketing_url": null,
            "setting_help_chat_url": null
          },
          "content": {
            "setting_use_app_layouts": true,
            "setting_use_app_elements": true,
            "setting_use_app_backgrounds": true,
            "setting_design_content_album_photo_limit": 100,
            "setting_design_content_album_limit": 5,
            "setting_layout_collection_limit": 5
          },
          "storefront": {
            "setting_hide_empty_storefronts_in_bm": false
          },
          "proofing": {
            "setting_use_simple_proofing": false,
            "setting_proofing_submit_book_cover_combined": false
          }
        },
        "contact_name": "Fake school contact",
        "contact_phone": "756 958 3124",
        "contact_email": "principal@fakeschool.com",
        "created_at": "2021-11-11",
        "has_active_license": true,
        "name": "Acme School",
        "publisher": {
          "id": 1,
          "name": "Acme Publisher",
          "primaryUsername": "acmepublisher"
        },
        "school_id": "acmeschool",
        "school_name": "Acme School",
        "users": [
          "mementopix",
          "editor-in-chief@acmeschool.com",
          "editor@acmeschool.com",
          "staffer@acmeschool.com"
        ]
      }
    },
  ],
  "meta": {
    "code": 200
  }
}

# Get School

GET school/:schoolStringId

This API returns information about a school. The ID supplied should be the string ID of the school, e.g. acmeschool and not the numeric ID. The string ID of the school is returned in school API responses as data.attributes.school_id.

Response (200)

{
  "data": {
      "type": "school",
      "id": "1",
      "attributes": {
        "active": true,
        "address": {
          "address_1": "Fake address line 1",
          "address_2": "Fake address line 2",
          "city": "Fake city",
          "zipcode": "91300",
          "country": "United States",
          "country_code": "US",
          "state": "CA",
          "province": null
        },
        "book_count": 1,
        "books": [
          {
            "id": "2581ca9a-4336-11ec-8128-080027d0ed3e",
            "admin_email": "nakedgun@gmail.com",
            "admin_first_name": "Test",
            "admin_last_name": "Editor-in-Chief",
            "book_due_date": "2022-07-11T00:00:00Z",
			"book_fixed_page_count": null,
            "book_type_id": "250c0a4e-4336-11ec-9d16-080027d0ed3e",
            "book_type_name": "8.5 x 11 Softcover",
            "book_invitation_email_status": "Not sent",
            "cover_due_date": "2022-02-11T00:00:00Z",
            "child_privacy_laws_applicable": false,
            "created_at": "2021-11-11T21:27:17Z",
            "form_factor_id": "600e93ab-9ac2-4732-81a2-97b90562b519",
            "is_setup": false,
            "license_valid": true,
            "license_expires_at": "2022-11-11 21:27:17",
            "name": "Acme School Yearbook",
            "users": [
              "mementopix",
              "editor-in-chief@acmeschool.com",
              "editor@acmeschool.com",
              "staffer@acmeschool.com"
            ],
            "storefront_id": "27ec2f3c-4336-11ec-a896-080027d0ed3e"
          }
        ],
        "config": {
          "help": {
            "setting_use_custom_help_system": false,
            "setting_help_knowledge_base_url": null,
            "setting_help_ticketing_url": null,
            "setting_help_chat_url": null
          },
          "content": {
            "setting_use_app_layouts": true,
            "setting_use_app_elements": true,
            "setting_use_app_backgrounds": true,
            "setting_design_content_album_photo_limit": 100,
            "setting_design_content_album_limit": 5,
            "setting_layout_collection_limit": 5
          },
          "storefront": {
            "setting_hide_empty_storefronts_in_bm": false
          },
          "proofing": {
            "setting_use_simple_proofing": false,
            "setting_proofing_submit_book_cover_combined": false
          }
        },
        "contact_name": "Fake school contact",
        "contact_phone": "756 958 3124",
        "contact_email": "principal@fakeschool.com",
        "created_at": "2021-11-11",
        "has_active_license": true,
        "name": "Acme School",
        "publisher": {
          "id": 1,
          "name": "Acme Publisher",
          "primaryUsername": "acmepublisher"
        },
        "school_id": "acmeschool",
        "school_name": "Acme School",
        "users": [
          "mementopix",
          "editor-in-chief@acmeschool.com",
          "editor@acmeschool.com",
          "staffer@acmeschool.com"
      }
    },
  ],
  "meta": {
    "code": 200
  }
}

This API may return 404 (not found) or 403 (forbidden - if you try to lookup a school which doesn't belong to you).

# Does school exist

POST doesSchoolExist

This API returns a boolean value to indicate whether the supplied school ID (string) exists. Typically, you would call this API before creating a school to ensure the school ID is not taken (either by yourself or another publisher).

Required params:

  • school_id
    • description: the string id of the school (e.g. acmeschool)
    • rules:
      • string

Response (200):

{
  "id": 1, // numeric ID of the school, or null if it doesn't exist
  "school_id": "acmeschool",
  "exists": true, // or false
  "meta": {
    "code": 200
  }
}

# Create School

POST school

This API creates a new school.

Required params:

  • name
    • description: the name of the school (e.g. Acme School)
    • rules:
      • string
  • schoolID
    • description: the id of the school (e.g. acmeschool)
    • rules:
      • string|max:100|unique

Optional params:

  • contactName
    • rules: max:60
  • contactPhone
    • rules: max:20
  • contactEmail
    • rules: max:20|email
  • addressLine1
    • rules: max:40
  • addressLine2
    • rules: max:40
  • addressCity
    • rules: max:40
  • addressZipCode
    • rules: max:8
  • addressState
    • rules: max:30
  • addressProvince
    • rules: max:30

TIP

When creating a new school, the country is automatically set to the same as your publisher account.

Response (200):

{
	"data": {
		"type": "school",
			"id": "5",
			"attributes": {
			"active": true,
				"address": {
				"address_1": null,
					"address_2": null,
					"city": null,
					"zipcode": null,
					"country": "Canada",
					"country_code": "CA",
					"state": null,
					"province": null
			},
			"book_count": 0,
				"books": [],
				"config": {
				"help": {
					"setting_use_custom_help_system": false,
                    "setting_help_knowledge_base_url": null,
                    "setting_help_ticketing_url": null,
                    "setting_help_chat_url": null
				},
				"content": {
					"setting_use_app_layouts": true,
                    "setting_use_app_elements": true,
                    "setting_use_app_backgrounds": true,
                    "setting_design_content_album_photo_limit": 100,
                    "setting_design_content_album_limit": 5,
                    "setting_layout_collection_limit": 5
				},
				"storefront": {
					"setting_hide_empty_storefronts_in_bm": false
				},
				"proofing": {
					"setting_use_simple_proofing": false,
                    "setting_proofing_submit_book_cover_combined": false
				}
			},
			"contact_name": null,
				"contact_phone": null,
				"contact_email": null,
				"created_at": "2021-12-06",
				"has_active_license": false,
				"name": "John Doe",
				"publisher": {
				"id": 1,
					"name": "Acme Publisher",
					"primaryUsername": "acmePublisher"
			},
			"school_id": "acmeschool",
				"school_name": "Acme school",
				"users": []
		}
	},
	"meta": {
		"code": 200
	}
}

This API may return 422 (unprocessable) or 403 (forbidden).

TIP

School IDs must be unique. You can check if the school ID exists before calling this API by using the doesSchoolExist API. If you supply a school ID which is already taken, this API will return the following error code (422):

{
    "meta": {
        "message": "SCHOOL_ALREADY_EXISTS",
        "code": 422
    }
}

# Book API

# Create Book

POST school/{schoolNumericId}/book (e.g. school/123/book)

This API creates a new book for a school.

TIP

Before you call this API, you must supply a book type id and school id.

  • you can list existing book types by calling GET book_types (supply the id as bookTypeId). Book types are created using the Book Product Dashboard (opens new window).
  • to create a school, call POST school and supply the id as schoolNumericId

For an existing school, call GET schools and supply the id as schoolNumericId.

Required params:

  • bookDueDate
    • description: The due date of the book
    • rules:
      • Valid future ISO 8601 date string, e.g: 2022-10-05T14:48:00.000Z
  • bookFixedPageCount
    • description: An optional fixed page count for the book
    • rules:
      • null|integer
      • Must be between the min/max page limit set by the book's product
      • API will return 422 FIXED_PAGE_COUNT_INVALID if it's not within the min/max page limit
    • note: Pass null or 0 to remove the fixed page count
  • coverDueDate
    • description: The due date of the cover
    • rules:
      • Valid future ISO 8601 date string, e.g: 2022-10-05T14:48:00.000Z
  • bookTypeId
    • description: The book type id (e.g. 0ee6faf4-4899-11ec-b9a6-080027d0ed3e) (this represents one of your book types, e.g. 8.5 x 11 Softcover)
    • rules:
      • string (GUID)
      • must be a valid book type ID which belongs to you.
  • bookName
    • description: The display name of the book
    • rules:
      • string|max:100
  • adminFirstName
    • description: The first name of the admin user
    • rules:
      • string|max:20
  • adminLastName
    • description: The last name of the admin user
    • rules:
      • string|max:20
  • adminEmail
    • description: The e-mail address of the school admin user.
    • rules:
      • string|email

Optional params:

  • coverSettings
    • description: The cover settings of the book. Controls what covers / inserts / endsheets are added.
    • rules:
      • array

Response (200):

{
	"type": "book",
    "id": "fc9450a2-56ff-11ec-896b-080027d0ed3e",
    "attributes": {
		"book_fixed_page_count": null,
		"book_type_id": "250c0a4e-4336-11ec-9d16-080027d0ed3e",
        "book_due_date": "2022-10-05T14:48:00Z",
        "cover_due_date": "2022-10-05T14:48:00Z",
        "name": "Test book",
        "publisher": "AcmePublisher",
        "school": "Acme School",
        "school_active": true,
        "type": "yearbook"
	},
    "meta": {
		"code": 200
	}
}

TIP

After the school is created, an invitation e-mail is sent to the school yearbook admin. In this e-mail they are given a link to setup the yearbook. This step requires the school yearbook admin to accept the Memento Yearbook terms of use, COPPA regulations and set their account password.

Cover Settings

The cover settings parameter for creating a book is optional. If you omit this parameter, the book will be setup with all available covers/inserts/endsheets that are defined in the book's form factor.

To control which covers are added to the book, you supply an array of cover settings objects. Each object describes the type of cover being added to the book, along with its inserts / endsheets.

This example shows all possible cover combinations that we support:

[
    {
      pageTypeKey: 'softCover', // add a soft cover to the book
      inserts: {
        pageTypeKey: 'softCoverInsert', // add inserts
        // for soft covers, this must be front and back (inside right, inside left)
        position: ['front', 'back'] 
      }
    },
    {
      pageTypeKey: 'hardCover', // add a hard cover to the book
      inserts: {
        pageTypeKey: 'hardCoverEndsheet', // add endsheets
        // for hard covers, this can be front/back, just front, just back
        position: ['front', 'back'] 
      }
    },
    {
      pageTypeKey: 'saddleStitchCover'
      // no inserts for a saddlestitch cover. Do not include the position property
    }
]

This example shows how to create a book with just a hard cover and no endsheets:

[
    {
      pageTypeKey: 'hardCover'
    }
]

If you supply page types which are not defined in the book's form factor, this API will return an error.

Note: pageTypeKey refers to the page type as defined in the form factor of the book product. The following keys are valid for covers:

  • softCover
  • hardCover
  • saddleStitchCover
  • cover (this is for older books which do not support different cover types)

The following keys are valid for the pageTypeKey for inserts and endsheets:

  • softCoverInsert (for a softCover)
  • hardCoverEndsheet (for a hardCover)

To determine which page types the current book supports:

  • list existing book types by calling GET book_types (supply the id as bookTypeId).
  • page types are listed under: attributes.form_factor.pageTypes

# Update Book

PUT book/{id} (e.g. book/fc9450a2-56ff-11ec-896b-080027d0ed3e)

This API updates information about an existing book.

Optional params:

  • name
    • description: The display name of the book
    • rules:
      • string|max:100
  • bookDueDate
    • description: The due date of the book
    • rules:
      • Valid future ISO 8601 date string, e.g: 2022-10-05T14:48:00.000Z
  • bookFixedPageCount
    • description: An optional fixed page count for the book
    • rules:
      • null|integer
      • Must be between the min/max page limit set by the book's product
      • API will return 422 FIXED_PAGE_COUNT_INVALID if it's not within the min/max page limit
    • note: Pass null or 0 to remove the fixed page count
  • coverDueDate
    • description: The due date of the cover
    • rules:
      • Valid future ISO 8601 date string, e.g: 2022-10-05T14:48:00.000Z
  • adminFirstName
    • description: The first name of the admin user
    • rules:
      • string|max:20
  • adminLastName
    • description: The last name of the admin user
    • rules:
      • string|max:20
  • adminEmail
    • description: The e-mail address of the school admin user.
    • rules:
      • string|email

Response (200):

{
	"type": "book",
    "id": "fc9450a2-56ff-11ec-896b-080027d0ed3e",
    "attributes": {
		"book_fixed_page_count": null,
		"book_type_id": "250c0a4e-4336-11ec-9d16-080027d0ed3e",
        "book_due_date": "2022-10-05T14:48:00Z",
        "cover_due_date": "2022-10-05T14:48:00Z",
        "name": "Test book",
        "publisher": "AcmePublisher",
        "school": "Acme School",
        "school_active": true,
        "type": "yearbook"
	},
    "meta": {
		"code": 200
	}
}

TIP

If you supply a new admin email, the user will be sent an invitation to join the yearbook.

# Team API

# Create Team Member

POST book/{bookId}/team/user (e.g. book/0416ad90-56ea-11ec-8729-080027d0ed3e/team/user)

Required params:

  • first_name
    • description: The first name of the user
    • rules:
      • string|max:20
  • last_name
    • description: The last name of the user
    • rules:
      • string|max:20
  • password
    • description: The password (plain text) of the user
    • rules:
      • string|min:6
  • role
    • description: The role of the user
    • rules:
      • string
      • must equal: editor_in_chief, editor or staffer
  • username
    • description: The username of the user
    • rules:
      • string|min:3
      • Important: The username should contain only letters and numbers. No special characters, tabs or spaces.

Optional params:

  • email
  • description: The email address of the user. If provided, they will be sent a confirmation email with their credentials and a link to access the yearbook.
    • rules:
      • string|email
  • permissions
  • description: Optional permissions to set for the user. This only applies to editor and staffer roles.
    • rules:
      • associate array, keyed by role
      • e.g. ['permissions']['editor'] = ['manage_portraits']
        • Editors can optionally have the manage_portraits permission.
      • e.g. ['permissions']['staffer'] = ['create_images', 'create_albums']
        • Staffers can optionally have the create_images and/or create_albums permissions.

# Book Types API

# Get Book Types

GET book_types

Response (200)

{
  "data": [
    {
      "type": "book_type",
      "id": "250c0a4e-4336-11ec-9d16-080027d0ed3e",
      "attributes": {
        "name": "8.5 x 11 Softcover",
        "type": "yearbook",
        "form_factor_id": "600e93ab-9ac2-4732-81a2-97b90562b519",
        "form_factor": {
          "type": "book",
          "version": 1,
          "name": "Sample Book",
          "sku": "BOOK_YB_001",
          "minDefaultPages": 20,
          "maxDefaultPages": 100,
          "pageStarting": "right",
          "totalPagesMultipleOf": 0,
          "pageTypes": {
            "single": {
              "unit": "inch",
              "pageType": "single",
              "pageHeight": 11,
              "pageWidth": 8.5,
              "safeZone": {
                "top": 0.25,
                "left": 0.25,
                "bottom": 0.25,
                "right": 0.25
              },
              "bleed": {
                "top": 0.15,
                "left": 0.15,
                "bottom": 0.15,
                "right": 0.15
              },
              "margins": {
                "top": 0.65,
                "left": 0.65,
                "bottom": 0.65,
                "right": 0.65
              }
            },
            "softCover": {
                "unit": "inch",
                "pageType": "cover",
                "displayName": "Soft Cover",
                "pageHeight": 12.7,
                "pageWidth": 19.9,
                "safeZone": {
                    "top": 0.25,
                    "left": 0.25,
                    "bottom": 0.25,
                    "right": 0.25
                },
                "bleed": {
                    "top": 0.15,
                    "left": 0.15,
                    "bottom": 0.15,
                    "right": 0.15
                },
                "margins": {
                    "top": 0.5,
                    "left": 0.5,
                    "bottom": 0.5,
                    "right": 0.5
                },
                "cover": {
                    "id": "softCover",
                    "coverInsertId": "softCoverInsert",
                    "spine": 0.75,
                    "orientation": "vertical",
                    "frontFlap": 0,
                    "backFlap": 0
                }
            },
            "hardCover": {
                "unit": "inch",
                "pageType": "cover",
                "displayName": "Hard Cover",
                "pageHeight": 12.7,
                "pageWidth": 19.9,
                "safeZone": {
                    "top": 0.25,
                    "left": 0.25,
                    "bottom": 0.25,
                    "right": 0.25
                },
                "bleed": {
                    "top": 0.15,
                    "left": 0.15,
                    "bottom": 0.15,
                    "right": 0.15
                },
                "margins": {
                    "top": 0.5,
                    "left": 0.5,
                    "bottom": 0.5,
                    "right": 0.5
                },
                "cover": {
                    "id": "hardCover",
                    "coverInsertId": "hardCoverEndsheet",
                    "spine": 0.75,
                    "orientation": "vertical",
                    "frontFlap": 0,
                    "backFlap": 0
                }
            },
            "softCoverInsert": {
                "unit": "inch",
                "pageType": "coverInsert",
                "pageHeight": 12.7,
                "pageWidth": 8.5,
                "safeZone": {
                    "top": 0.25,
                    "left": 0.25,
                    "bottom": 0.25,
                    "right": 0.25
                },
                "bleed": {
                    "top": 0.15,
                    "left": 0.15,
                    "bottom": 0.15,
                    "right": 0.15
                },
                "margins": {
                    "top": 0.5,
                    "left": 0.5,
                    "bottom": 0.5,
                    "right": 0.5
                },
                "coverInsert": {
                    "parentId": "softCover"
                }
            },
            "hardCoverEndsheet": {
                "unit": "inch",
                "pageType": "coverInsert",
                "pageHeight": 12.7,
                "pageWidth": 19.9,
                "safeZone": {
                    "top": 0.25,
                    "left": 0.25,
                    "bottom": 0.25,
                    "right": 0.25
                },
                "bleed": {
                    "top": 0.15,
                    "left": 0.15,
                    "bottom": 0.15,
                    "right": 0.15
                },
                "margins": {
                    "top": 0.5,
                    "left": 0.5,
                    "bottom": 0.5,
                    "right": 0.5
                },
                "cover": {
                    "spine": 0.75,
                    "orientation": "vertical",
                    "frontFlap": 0,
                    "backFlap": 0
                },
                "coverInsert": {
                    "parentId": "hardCover"
                }
            },
            "saddleStitchCover": {
                "unit": "inch",
                "pageType": "cover",
                "pageHeight": 12.7,
                "pageWidth": 19.9,
                "safeZone": {
                    "top": 0.25,
                    "left": 0.25,
                    "bottom": 0.25,
                    "right": 0.25
                },
                "bleed": {
                    "top": 0.15,
                    "left": 0.15,
                    "bottom": 0.15,
                    "right": 0.15
                },
                "margins": {
                    "top": 0.5,
                    "left": 0.5,
                    "bottom": 0.5,
                    "right": 0.5
                },
                "cover": {
                    "spine": 0.75,
                    "orientation": "vertical",
                    "frontFlap": 0,
                    "backFlap": 0
                }
            }
          },
          "outputSettings": {
            "dpi": 300,
            "splitCover": "none",
            "outputType": "pdf",
            "pdfOutput": "oneFileForBookAndCover",
            "dpiError": 100,
            "dpiWarning": 150
          },
          "id": "600e93ab-9ac2-4732-81a2-97b90562b519"
        },
        "publisher_name": "AcmePublisher",
        "in_use": true,
        "book_count": 12
      }
    }
  ],
  "meta": {
    "code": 200
  }
}