NAV

API Reference

Introduction

Welcome to the Xeparrot Developer Documentation V0.0.1. You can use this API to access XeParrot endpoints, which can get information of various shoppers, products, webauthn, auth, payment details and addresses in the database.

We have language bindings in curl You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.

Install

Download

Download the files above and place on your server.

Environment Files

This package ships with a .env.example file in the root of the project.

You must rename this file to just .env

Composer

XeParrot project dependencies are managed through the PHP Composer tool. The first step is to install the depencencies by navigating into your project in terminal and typing this command

composer install

NPM or YARN

In order to install the Javascript packages for frontend development, you will need the Node Package Manager, and optionally the Yarn Package Manager by Facebook (Recommended)

If you only have NPM installed you have to run this command from the root of the project:

npm install

If you have Yarn installed, run this instead from the root of the project:

yarn

Create Database

You must create your database on your server and on your .env file update the following lines:


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

Change these lines to reflect your new database settings.

Artisan Commands

Generate Key

The first thing we are going to do is set the key that Laravel will use when doing encryption.


php artisan key:generate

Migrate Database

You should see a green message stating your key was successfully generated. As well as you should see the APP_KEY variable in your .env file reflected.

It's time to see if your database credentials are correct.

We are going to run the built in migrations to create the database tables:


php artisan migrate

Seeds Dummy Data

You should see a message for each table migrated, if you don't and see errors, than your credentials are most likely not correct.

We are now going to set the administrator account information. To do this you need to navigate to this file and change the name/email/password of the Administrator account.

You can delete the other dummy users, but do not delete the administrator account or you will not be able to access the backend.

Now seed the database with:


php artisan db:seed

You should get a message for each file seeded, you should see the information in your database tables.

NPM Run '*'

Now that you have the database tables and default rows, you need to build the styles and scripts.

Run NPM on your Application

These files are generated using Laravel Mix, which is a wrapper around many tools, and works off the webpack.mix.js in the root of the project.

You can build with:


npm run <command>

The available commands are listed at the top of the package.json file under the 'scripts' key.

You will see a lot of information flash on the screen and then be provided with a table at the end explaining what was compiled and where the files live.

At this point you are done, you should be able to hit the project in your local browser and see the project, as well as be able to log in with the administrator and view the backend

PHP Unit

After your project is installed, make sure you run the test suite to make sure all of the parts are working correctly. From the root of your project run:


php artisan phpunit

You will see a dot(.) appear for each of the hundreds of tests, and then be provided with the amount of passing tests at the end. There should be no failures with a fresh install.

After your project is installed you must run this command to link your public storage folder for user avatar uploads:


php artisan storage:link

Structure

Domain Structure

The structure of each domain is up to you, but is good practice to just follow the default Laravel app folder structure.

For example, the Auth domain has code relevant to the authentication/authorization portion of the application, and is broken down into all the relevant folders: Events/Http/Listeners/Models/etc. These are just namespaced files placed here instead of normally like App/Http/Auth it's App/Domains/Auth/Http.

Events

Note: All current events in this project are processed with a like-named listener class that is registered in EventServiceProvider and stored in that domains Listeners directory.

Most events are used to log information using spaties activity-log package.

Some events have extra functionality:

Middleware

There are many included middleware that are not Laravel default:

Requests

This method is opinionated, so refactor how you see fit.

Form requests are used where validation or authorization is needed for a request (and a policy isn't the best choice for the given request) and is injected into the controllers action signature.

Form requests are not used in Laravel's default auth scaffolding controllers where a validate() method is supplied such as login and register.

Models

Models are organized by domain, and furthermore I use traits to organize each model:

Model properties such as $dates, $casts, $appends, and $with are used where necessary.

Observers

There is one observer included with the project, that is registered in the ObserverServiceProvider:

Rules

There is one rule included with the project, that is used in any request dealing with password changes:

Services

Services are classes to attempt to extract database logic out of the controllers.

There is a BaseService class you can extend, who's constructor accepts a model and inherits some useful functionality such as get(), count(), find(), etc.

Example:

Instead of duplicating this line everywhere:

$user = User::findOrFail($id);

You can use:

$user = resolve(UserService::class)->findOrFail($id);

It's longer, but it's extracted out to one place in the codebase instead of duplicating logic everywhere. This is just an example, and a one liner usually isn't a big deal, but extracting out multi-line logic that doesn't belong in a model or elsewhere is good to have in a service dedicated to one model.

Exceptions

Admittedly, the exception classes could be more descriptive, and that is a goal for the next version.

But for now, there are two non-laravel exceptions that can be used:

Helpers

Though some people say it's not a good design pattern to have helper classes, I found this method easier to organize than just including a helpers.php file in composers file section.

The App\Helpers directory comes with one folder:

Liveware

This project includes Laravel Livewire as a dependency because it makes use of my Laravel Livewire Tables plugin for the datatables functionality.

You can find all Livewire components in the App\Http\Livewire directory.

Configuration

All of the configurable items of the xeparrot can be found in the config/engine.php file. Each item should have a relevant doc block.

There may be other configuration files published by default from some packages such as activitylog, permission, geoip, etc.

Resource Structure

This project follows standard Laravel resource folder structure.

Javascript

The javascript files are as follows:

Language

All language files for this version of the xeparrot are in JSON format except default Laravel files and package languages if published.

SCSS

The SCSS files are as follows:

View

The views are structured much like the rest of the application, frontend/backend/etc. They usually follow the namespace structure.

There's only one folder to note, and that is components which are blade components used throughout the blade files. At the time of this writing they are all anonymous components, or they don't have an associated class and just work off of the props passed into them.

XeModule

Quick Example

Generate your first xemodule using php artisan xemodule:make Blog . The following structure will be generated.

app/
bootstrap/
vendor/
Modules/
  ├── Blog/
      ├── Assets/
      ├── Config/
      ├── Console/
      ├── Database/
          ├── Migrations/
          ├── Seeders/
      ├── Entities/
      ├── Http/
          ├── Controllers/
          ├── Middleware/
          ├── Requests/
      ├── Providers/
          ├── BlogServiceProvider.php
          ├── RouteServiceProvider.php
      ├── Resources/
          ├── assets/
              ├── js/
                ├── app.js
              ├── sass/
                ├── app.scss
          ├── lang/
          ├── views/
      ├── Routes/
          ├── api.php
          ├── web.php
      ├── Repositories/
      ├── Tests/
      ├── composer.json
      ├── module.json
      ├── package.json
      ├── webpack.mix.js

Create Module

Creating a xemodule is simple and straightforward. Run the following command to create a xemodule.


php artisan xemodule:make <xemodule-name>

Replace by your desired name.

It is also possible to create multiple xemodules in one command.

php artisan xemodule:make Blog User Auth

By default when you create a new xemodule, the command will add some resources like a controller, seed class, service provider, etc. automatically. If you don't want these, you can add --plain flag, to generate a plain xemodule.

php artisan xemodule:make Blog --plain
# or
php artisan xemodule:make Blog -p

Naming convention

Because we are autoloading the xemodules using psr-4, we strongly recommend using StudlyCase convention.

Folder Structure

app/
bootstrap/
vendor/
Modules/
  ├── Blog/
      ├── Assets/
      ├── Config/
      ├── Console/
      ├── Database/
          ├── Migrations/
          ├── Seeders/
      ├── Entities/
      ├── Http/
          ├── Controllers/
          ├── Middleware/
          ├── Requests/
          ├── routes.php
      ├── Providers/
          ├── BlogServiceProvider.php
      ├── Resources/
          ├── lang/
          ├── views/
      ├── Repositories/
      ├── Tests/
      ├── composer.json
      ├── module.json
      ├── start.php

Custom Name Spaces

When you create a new xemodule it also registers new custom namespace for Lang, View and Config. For example, if you create a new xemodule named blog, it will also register new namespace/hint blog for that xemodule. Then, you can use that namespace for calling Lang, View or Config. Following are some examples of its usage:

Calling Lang:

Lang::get('blog::group.name');

@trans('blog::group.name');

Calling View:

view('blog::index')

view('blog::partials.sidebar')

Calling Config:


Config::get('blog.name')

Default namespace

What the default namespace will be when generating xemodules.

Key: namespace

Default: Modules

Overwrite the generated files

Overwrite the default generated stubs to be used when generating xemodules. This can be useful to customise the output of different files.

Key: stubs

Overwrite the paths

Overwrite the default paths used throughout the package.

Key: paths

Scan additional folders for xemodules

This is disabled by default. Once enabled, the package will look for xemodules in the specified array of paths.

Key: scan

Composer file template

Customise the generated composer.json file.

Key: composer

Caching

If you have many xemodules it's a good idea to cache this information (like the multiple xemodule.json files for example).

Key: cache

Registering custom namespace

Decide which custom namespaces need to be registered by the package. If one is set to false, the package won't handle its registration.

Key: register

Helpers

Module path function

Get the path to the given xemodule.

$path = module_path('Blog');

Compiling Assets

Installation & Setup

When you create a new xemodule it also create assets for CSS/JS and the webpack.mix.js configuration file.

php artisan xemodule:make Blog

Change directory to the xemodule:

cd Modules/Blog

The default package.json file includes everything you need to get started. You may install the dependencies it references by running:

npm install

Running Mix

Mix is a configuration layer on top of Webpack, so to run your Mix tasks you only need to execute one of the NPM scripts that is included with the default laravel-xemodules package.json file

// Run all Mix tasks...
npm run dev

// Run all Mix tasks and minify output...
npm run production

After generating the versioned file, you won't know the exact file name. So, you should use Laravel's global mix function within your views to load the appropriately hashed asset. The mix function will automatically determine the current name of the hashed file:

// Modules/Blog/Resources/views/layouts/master.blade.php

<link rel="stylesheet" href="{{ mix('css/blog.css') }}">

<script src="{{ mix('js/blog.js') }}"></script>

For more info on Laravel Mix view the documentation here: https://laravel.com/docs/mix

Install laravel-mix-merge-manifest

npm install laravel-mix-merge-manifest --save-dev

Modify webpack.mix.js main file

let mix = require('laravel-mix');


/* Allow multiple Laravel Mix applications*/
require('laravel-mix-merge-manifest');
mix.mergeManifest();
/*----------------------------------------*/

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

Artisan commands

Note all the following commands use "Blog" as example xemodule name, and example class/file names

Utility commands

xemodule:make

Generate a new xemodule.

php artisan xemodule:make Blog

xemodule:make

Generate multiple xemodules at once.

php artisan xemodule:make Blog User Auth

xemodule:use

Use a given xemodule. This allows you to not specify the xemodule name on other commands requiring the xemodule name as an argument.

php artisan xemodule:use

xemodule:unuse

This unsets the specified xemodule that was set with the xemodule:use command.

php artisan xemodule:unuse

xemodule:list

List all available xemodules.

php artisan xemodule:list

xemodule:migrate

Migrate the given xemodule, or without a xemodule an argument, migrate all xemodules.

php artisan xemodule:migrate Blog

xemodule:migrate-rollback

Rollback the given xemodule, or without an argument, rollback all xemodules.

php artisan xemodule:migrate-rollback Blog

xemodule:migrate-refresh

Refresh the migration for the given xemodule, or without a specified xemodule refresh all xemodules migrations.

xemodule:migrate-reset Blog

Reset the migration for the given xemodule, or without a specified xemodule reset all xemodules migrations.

php artisan xemodule:migrate-reset Blog

xemodule:seed

Seed the given xemodule, or without an argument, seed all xemodules

php artisan xemodule:seed Blog

xemodule:publish-migration

Publish the migration files for the given xemodule, or without an argument publish all xemodules migrations.

php artisan xemodule:publish-migration Blog

xemodule:publish-config

Publish the given xemodule configuration files, or without an argument publish all xemodules configuration files.

php artisan xemodule:publish-config Blog

xemodule:publish-translation

Publish the translation files for the given xemodule, or without a specified xemodule publish all xemodules migrations.

php artisan xemodule:publish-translation Blog

xemodule:enable

Enable the given xemodule.

php artisan xemodule:enable Blog

xemodule:disable

Disable the given xemodule.

php artisan xemodule:disable Blog

xemodule:update

Update the given xemodule.

php artisan xemodule:update Blog

Generator commands

xemodule:make-command

Generate the given console command for the specified xemodule.

php artisan xemodule:make-command CreatePostCommand Blog

xemodule:make-migration

Generate a migration for specified xemodule.

php artisan xemodule:make-migration create_posts_table Blog

xemodule:make-seed

Generate the given seed name for the specified xemodule.

php artisan xemodule:make-seed seed_fake_blog_posts Blog

xemodule:make-controller

Generate a controller for the specified xemodule.

php artisan xemodule:make-controller PostsController Blog

xemodule:make-model

Generate the given model for the specified xemodule.

php artisan xemodule:make-model Post Blog

Optional options: * --fillable=field1,field2: set the fillable fields on the generated model * --migration, -m: create the migration file for the given model

xemodule:make-provider

Generate the given service provider name for the specified xemodule.

php artisan xemodule:make-provider BlogServiceProvider Blog

xemodule:make-middleware

Generate the given middleware name for the specified xemodule.

php artisan xemodule:make-middleware CanReadPostsMiddleware Blog

xemodule:make-mail

Generate the given mail class for the specified xemodule.

php artisan xemodule:make-mail SendWeeklyPostsEmail Blog

xemodule:make-mail

Generate the given mail class for the specified xemodule.

php artisan xemodule:make-mail SendWeeklyPostsEmail Blog

xemodule:make-notification

Generate the given notification class name for the specified xemodule.

php artisan xemodule:make-notification NotifyAdminOfNewComment Blog

xemodule:make-listener

Generate the given listener for the specified xemodule. Optionally you can specify which event class it should listen to. It also accepts a --queued flag allowed queued event listeners.

php artisan xemodule:make-listener NotifyUsersOfANewPost Blog
php artisan xemodule:make-listener NotifyUsersOfANewPost Blog --event=PostWasCreated
php artisan xemodule:make-listener NotifyUsersOfANewPost Blog --event=PostWasCreated --queued

xemodule:make-request

Generate the given request for the specified xemodule.

php artisan xemodule:make-request CreatePostRequest Blog

xemodule:make-event

Generate the given event for the specified xemodule.

php artisan xemodule:make-event BlogPostWasUpdated Blog

xemodule:make-job

Generate the given job for the specified xemodule.

php artisan xemodule:make-job JobName Blog

php artisan xemodule:make-job JobName Blog --sync # A synchronous job class

xemodule:route-provider

Generate the given route service provider for the specified xemodule.

php artisan xemodule:route-provider Blog

xemodule:make-factory

Generate the given database factory for the specified xemodule.

php artisan xemodule:make-factory FactoryName Blog

xemodule:make-policy

Generate the given policy class for the specified xemodule.

The Policies is not generated by default when creating a new xemodule. Change the value of paths.generator.policies in xemodules.php to your desired location.

php artisan xemodule:make-policy PolicyName Blog

xemodule:make-rule

Generate the given validation rule class for the specified xemodule.

The Rules folder is not generated by default when creating a new xemodule. Change the value of paths.generator.rules in xemodules.php to your desired location.

php artisan xemodule:make-rule ValidationRule Blog

xemodule:make-resource

Generate the given resource class for the specified xemodule. It can have an optional --collection argument to generate a resource collection.

The Transformers folder is not generated by default when creating a new xemodule. Change the value of paths.generator.resource in xemodules.php to your desired location.

php artisan xemodule:make-resource PostResource Blog
php artisan xemodule:make-resource PostResource Blog --collection

xemodule:make-test

Generate the given test class for the specified xemodule.

php artisan xemodule:make-test EloquentPostRepositoryTest Blog

Facade methods

Get all modules.

Module::all();

Get all cached modules.

Module::getCached()

Get Ordered

Get ordered modules. The modules will be ordered by the priority key in module.json file.

Module::getOrdered();

Get Scanned

Get scanned modules.

Module::scan();

Find Modules

Find a specific module.

Module::find('name');
// OR
Module::get('name');

Find a Module

Find a module, if there is one, return the Module instance, otherwise throw Nwidart\Modules\Exeptions\ModuleNotFoundException.

Module::findOrFail('module-name');

Scanned Paths

Get scanned paths.

Module::getScanPaths();

Collection Modules

Get all modules as a collection instance.

Module::toCollection();

Module Status

Get modules by the status. 1 for active and 0 for inactive.

Module::getByStatus(1);

Check Specific Module

Check the specified module. If it exists, will return true, otherwise false.

Module::has('blog');

Get All Enabled Modules

Get all enabled modules.

Module::allEnabled();

Get All Disabled Modules

Get all disabled modules.

Module::allDisabled();

Get Count of all Modules

Get count of all modules.

Module::count();

Module Path

Get module path.

Module::getPath();

Register Modules

Register the modules.

Module::register();

Module Methods

Get an entity from a specific module.

$module = Module::find('blog');

Get module name.

$module->getName();

Get module name in lowercase.

$module->getLowerName();

Get module name in studlycase.

$module->getStudlyName();

Get module path.

$module->getPath();

Get extra path.

$module->getExtraPath('Assets');

Disable the specified module.

$module->disable();

Enable the specified module.

$module->enable();

Delete the specified module.

$module->delete();

Get Requires

Get an array of module requirements. Note: these should be aliases of the module.

$module->getRequires();

Module Resources

Your module will most likely contain what laravel calls resources, those contain configuration, views, translation files, etc. In order for you module to correctly load and if wanted publish them you need to let laravel know about them as in any regular package.

Configuration

$this->publishes([
    __DIR__.'/../Config/config.php' => config_path('blog.php'),
], 'config');
$this->mergeConfigFrom(
    __DIR__.'/../Config/config.php', 'blog'
);

Module Views

$viewPath = base_path('resources/views/modules/blog');

$sourcePath = __DIR__.'/../Resources/views';

$this->publishes([
    $sourcePath => $viewPath
]);

$this->loadViewsFrom(array_merge(array_map(function ($path) {
    return $path . '/modules/blog';
}, \Config::get('view.paths')), [$sourcePath]), 'blog');

The main part here is the loadViewsFrom method call. If you don't want your views to be published to the laravel views folder, you can remove the call to the $this->publishes() call.

Language files

 $langPath = base_path('resources/lang/modules/blog');

if (is_dir($langPath)) {
    $this->loadTranslationsFrom($langPath, 'blog');
} else {
    $this->loadTranslationsFrom(__DIR__ .'/../Resources/lang', 'blog');
}

Factories

If you want to use laravel factories you will have to add the following in your service provider:

$this->app->singleton(Factory::class, function () {
    return Factory::construct(__DIR__ . '/Database/factories');
});

Module Console Commands

Your module may contain console commands. You can generate these commands manually, or with the following helper:

php artisan module:make-command CreatePostCommand Blog

This will create a CreatePostCommand inside the Blog module. By default this will be Modules/Blog/Console/CreatePostCommand.

Please refer to the laravel documentation on artisan commands to learn all about them.

Registering the command

You can register the command with the laravel method called commands that is available inside a service provider class.

$this->commands([
    \Modules\Blog\Console\CreatePostCommand::class,
]);

You can now access your command via php artisan in the console.

Registering Module Events

Your module may contain events and event listeners. You can create these classes manually, or with the following helpers:

php artisan module:make-event BlogPostWasUpdated Blog
php artisan module:make-listener NotifyAdminOfNewPost Blog

Once those are create you need to register them in laravel. This can be done in 2 ways:

Creating an EventServiceProvider

Once you have multiple events, you might find it easier to have all events and their listeners in a dedicated service provider. This is what the EventServiceProvider is for.

Create a new class called for instance EventServiceProvider in the Modules/Blog/Providers folder (Blog being an example name).

This class needs to look like this:

<?php

namespace Modules\Blog\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [];
}

Menu Management

Quick Example

// Menu.php
Menu::create('navbar', function($menu) {
    $menu->url('/', 'Home', 1);
    $menu->route('/', 'About', ['user' => '1'], 2);
    $menu->dropdown('Settings', function ($sub) {
        $sub->header('ACCOUNT');
        $sub->url('/settings/design', 'Design');
        $sub->divider();
        $sub->url('logout', 'Logout');
    }, 3);
});

// main.blade.php
{!! Menu::get('navbar') !!}

Creating Menu

You can define your menus in your desired file / class, as long as it is autoload by composer.

To create a menu, simply call the create method from Menu facade. The first parameter is the menu name and the second parameter is callback for defining menu items.

Menu::create('navbar', function($menu) {
    // define your menu items here
});

As explained before, we can defining menu item in the callback by accessing $menu variable, which the variable is instance of Nwidart\Menus\MenuBuilder class.

To defining a plain URL, you can use ->url() method.

Menu::create('navbar', function($menu) {
    // URL, Title, Attributes
    $menu->url('home', 'Home', ['target' => 'blank']);
});

If you have named route, you define the menu item by calling ->route() method.

Menu::create('navbar', function($menu) {
    $menu->route(
        'users.show', // route name
        'View Profile', // title
        ['id' => 1], // route parameters
        ['target' => 'blank'] // attributes
    );
});

You can also defining the menu item via array by calling ->add() method.

Menu::create('navbar', function($menu) {
    $menu->add([
        'url' => 'about',
        'title' => 'About',
        'attributes' => [
            'target' => '_blank'
        ]
    ]);

    $menu->add([
        'route' => ['profile', ['user' => 'nwidart']],
        'title' => 'Visit My Profile',
        'attributes' => [
            'target' => '_blank'
        ]
    ]);
});

To create a dropdown menu, you can call to ->dropdown() method and passing the first parameter by title of dropdown and the second parameter by closure callback that retrieve $sub variable. The $sub variable is the the instance of Nwidart\Menus\MenuItem class.

Menu::create('navbar', function($menu) {
    $menu->url('/', 'Home');
    $menu->dropdown('Settings', function ($sub) {
        $sub->url('settings/account', 'Account');
        $sub->url('settings/password', 'Password');
        $sub->url('settings/design', 'Design');
    });
});

You can also create a dropdown inside dropdown by using ->dropdown() method. This will allow to to create a multilevel menu items.

Menu::create('navbar', function($menu) {
    $menu->url('/', 'Home');
    $menu->dropdown('Account', function ($sub) {
        $sub->url('profile', 'Visit My Profile');
        $sub->dropdown('Settings', function ($sub) {
            $sub->url('settings/account', 'Account');
            $sub->url('settings/password', 'Password');
            $sub->url('settings/design', 'Design');
        });
        $sub->url('logout', 'Logout');
    });
});

Admin Pages

Define Controllers

Xeparrot allows to create backend level admin pages, so first thing you should add this service on your created controller

use App\Services\SettingPageGeneratorBackend;

Now you can define forms controllers components

  $adminPage = new SettingPageGeneratorBackend('title','views','post_url');
Parameter Type Description
title string Title of setting pages.
views string Return view page name.
post_url string form post route

Add form controllers

Follow this example, you can define form components

 $adminPage->addController(
            'name',
            'is_required,
            'label',
            'description',
            'category',
            'type',
            'value');
Parameter Type Description
name string component name.
is_required bool Return view page name.
label string form post route
description text description
category string category name
type string controller components types
value string field values
data array external data list

Form component types

Type Description
text text components
select drop down component
textarea text area field
file file uploader field

Example Form

Following this example


$settingPageGenerator = new SettingPageGeneratorBackend('FileManager','values','https://hellocom.com');



        $settingPageGenerator->addController(
            'project_name',
                true,
                'Project Name',
                'Please enter your project name',
                'Projects',
                'text',
                'hello');


        $settingPageGenerator->addController(
            'project_example',
            true,
            'Project Example',
            'This is best example label',
            'Hello',
            'select',
                'values2',[
            [
                'name' => 'Sanjaya Senevirathne',
                'value' => 'values'

            ],
            [
                'name' => 'Kumara Bandara',
                'value' => 'values2'
            ]
        ]);

        $settingPageGenerator->addController(
            'project_name',
            false,
            'Project Name',
            'Please enter your project name',
            'Projects',
            'textarea',
            'hello');


        $settingPageGenerator->addController(
            'project_name',
            true,
            'Project Name',
            'Please enter your project name',
            'Projects',
            'file',
            'hello');

        $settingPageGenerator->renderControllers();
        $category = $settingPageGenerator->getContent();

        return view($settingPageGenerator->renderPage(),[
            'formData' => $category,
            'formURL' => ''
        ]);

Errors

The AdUp.io Shopper API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The kitten requested is hidden for administrators only.
404 Not Found -- The specified kitten could not be found.
405 Method Not Allowed -- You tried to access a kitten with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The kitten requested has been removed from our servers.
418 I'm a teapot.
429 Too Many Requests -- You're requesting too many kittens! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.