MENU navbar-image

Introduction

REST API for the Dokio multi-vendor marketplace platform.

Welcome to the **Dokio API**. This reference covers authentication, users, stores, products, categories, and related resources.

## Base URL

All endpoints are prefixed with `/api`. Versioned resources live under `/api/v1`.

## Response format

Successful responses typically follow this shape:

```json
{
    "status": 200,
    "message": "…",
    "data": {}
}
```

Error responses return:

```json
{
    "status": 400,
    "message": "…"
}
```

Resources use a JSON:API-inspired structure with `type`, `id`, `attributes`, `relationships`, and `links`.

<aside>
As you scroll, you'll see code examples in the dark panel on the right (or inline on mobile).
Switch languages with the tabs at the top right.
</aside>

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Obtain a token by calling **POST /api/login** or **POST /api/register**.
Tokens are Laravel Sanctum personal access tokens and expire after one month.
Pass the token as: `Authorization: Bearer {token}`.
Email verification is required before login succeeds.

Authentication

Register, log in, verify email, and manage your session.

Current user

requires authentication

Return the authenticated user, including their store when available.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/me" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/me"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/me';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "User fetched successfully",
    "data": {
        "type": "user",
        "id": "1",
        "attributes": {
            "name": "Jane Doe",
            "email": "jane@example.com"
        },
        "relationships": {
            "store": {
                "data": {
                    "id": "1",
                    "type": "store"
                }
            },
            "links": {
                "self": "https://api.dokio.local/api/v1/stores/1"
            }
        }
    }
}
 

Request      

GET api/me

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Log in

Authenticate with email and password. Returns a Sanctum token valid for one month. The account must be email-verified.

Example request:
curl --request POST \
    "https://dokio.shop/api/login" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"jane@example.com\",
    \"password\": \"password123\"
}"
const url = new URL(
    "https://dokio.shop/api/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "jane@example.com",
    "password": "password123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/login';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'jane@example.com',
            'password' => 'password123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful login):


{
    "status": 200,
    "message": "Logged in successfully",
    "data": {
        "token": "1|abcXYZ...",
        "verified": true
    }
}
 

Example response (400, Email not verified):


{
    "errors": [
        {
            "status": "400",
            "code": "email.not_verified",
            "detail": "Email not verified"
        }
    ]
}
 

Example response (401, Invalid credentials):


{
    "errors": [
        {
            "status": "401",
            "code": "credentials.invalid",
            "detail": "Invalid credentials"
        }
    ]
}
 

Request      

POST api/login

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

email   string     

The user email address. Must be a valid email address. Example: jane@example.com

password   string     

The account password (minimum 8 characters). Must be at least 8 characters. Example: password123

Register

Create a new user account and receive a Sanctum token. A verification email is sent automatically.

Example request:
curl --request POST \
    "https://dokio.shop/api/register" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Jane Doe\",
    \"email\": \"jane@example.com\",
    \"password\": \"password123\"
}"
const url = new URL(
    "https://dokio.shop/api/register"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "password": "password123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/register';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Jane Doe',
            'email' => 'jane@example.com',
            'password' => 'password123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "User registered successfully",
    "data": {
        "token": "1|abcXYZ...",
        "verified": false
    }
}
 

Request      

POST api/register

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

name   string     

The user full name. Must not be greater than 255 characters. Example: Jane Doe

email   string     

A unique email address for the account. Must be a valid email address. Example: jane@example.com

password   string     

The account password (minimum 8 characters). Must be at least 8 characters. Example: password123

Register or log in with Google

Authenticate with a Google ID token from the client. Creates an account if needed, or links Google to an existing email account. Returns a Sanctum token valid for one month.

Example request:
curl --request POST \
    "https://dokio.shop/api/auth/google" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"id_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\"
}"
const url = new URL(
    "https://dokio.shop/api/auth/google"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/auth/google';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'id_token' => 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful Google authentication):


{
    "status": 200,
    "message": "Logged in successfully",
    "data": {
        "token": "1|abcXYZ...",
        "verified": true
    }
}
 

Example response (400, Google account email is not verified):


{
    "errors": [
        {
            "status": "400",
            "code": "google.email_not_verified",
            "detail": "Google email not verified"
        }
    ]
}
 

Example response (401, Invalid or expired ID token):


{
    "errors": [
        {
            "status": "401",
            "code": "google.invalid_id_token",
            "detail": "Invalid Google token"
        }
    ]
}
 

Request      

POST api/auth/google

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

id_token   string     

The Google ID token obtained from Google Sign-In on the client. Example: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Register or log in with a Google authorization code

Exchange a one-time Google popup code for an ID token, then authenticate the user. The request Origin must match FRONTEND_URL and X-Requested-With must be XMLHttpRequest. Returns a Sanctum token valid for one month.

Example request:
curl --request POST \
    "https://dokio.shop/api/auth/google/code" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"code\": \"synthetic-google-authorization-code\"
}"
const url = new URL(
    "https://dokio.shop/api/auth/google/code"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "synthetic-google-authorization-code"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/auth/google/code';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'code' => 'synthetic-google-authorization-code',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Successful Google authentication):


{
    "status": 200,
    "message": "Logged in successfully",
    "data": {
        "token": "1|abcXYZ...",
        "verified": true
    }
}
 

Example response (401, Invalid or expired authorization code):


{
    "errors": [
        {
            "status": "401",
            "code": "google.invalid_code",
            "detail": "Invalid Google authorization code"
        }
    ]
}
 

Example response (403, Request origin is not the configured dashboard origin):


{
    "errors": [
        {
            "status": "403",
            "code": "google.invalid_origin",
            "detail": "Invalid Google sign-in origin"
        }
    ]
}
 

Request      

POST api/auth/google/code

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

code   string     

The one-time authorization code returned by the Google popup. Example: synthetic-google-authorization-code

Forgot password

Send a password reset email if the account exists.

Example request:
curl --request POST \
    "https://dokio.shop/api/forgot-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"jane@example.com\"
}"
const url = new URL(
    "https://dokio.shop/api/forgot-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "jane@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/forgot-password';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'email' => 'jane@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Password reset email sent",
    "data": []
}
 

Example response (404):


{
    "errors": [
        {
            "status": "404",
            "code": "user.not_found",
            "detail": "User not found"
        }
    ]
}
 

Request      

POST api/forgot-password

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

email   string     

The email address of the account to reset. Must be a valid email address. Example: jane@example.com

Reset password

Set a new password using the token from the reset email. All existing tokens are revoked.

Example request:
curl --request POST \
    "https://dokio.shop/api/reset-password" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"token\": \"abc123resetToken\",
    \"email\": \"jane@example.com\",
    \"password\": \"newpassword123\"
}"
const url = new URL(
    "https://dokio.shop/api/reset-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": "abc123resetToken",
    "email": "jane@example.com",
    "password": "newpassword123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/reset-password';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'token' => 'abc123resetToken',
            'email' => 'jane@example.com',
            'password' => 'newpassword123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Password reset successfully",
    "data": []
}
 

Example response (400):


{
    "errors": [
        {
            "status": "400",
            "code": "passwords.reset_failed",
            "detail": "Failed to reset password"
        }
    ]
}
 

Request      

POST api/reset-password

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

token   string     

The password reset token from the email link. Example: abc123resetToken

email   string     

The email address of the account being reset. Must be a valid email address. Example: jane@example.com

password   string     

The new password (minimum 8 characters). Must be at least 8 characters. Example: newpassword123

Log out

requires authentication

Revoke the current access token.

Example request:
curl --request POST \
    "https://dokio.shop/api/logout" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/logout"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/logout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Logged out successfully",
    "data": []
}
 

Request      

POST api/logout

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Verify email

Confirm the user email address using the link from the verification email.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/email/verify/1/a1b2c3d4e5f6" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/email/verify/1/a1b2c3d4e5f6"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/email/verify/1/a1b2c3d4e5f6';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Email verified successfully",
    "data": {
        "token": "1|abcXYZ...",
        "verified": true
    }
}
 

Example response (400):


{
    "errors": [
        {
            "status": "400",
            "code": "verification.invalid_link",
            "detail": "Invalid verification link"
        }
    ]
}
 

Example response (400):


{
    "errors": [
        {
            "status": "400",
            "code": "verification.email_already_verified",
            "detail": "Email already verified"
        }
    ]
}
 

Request      

GET api/email/verify/{id}/{hash}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The user ID. Example: 1

hash   string     

SHA1 hash of the user email (from the verification link). Example: a1b2c3d4e5f6

Users

Retrieve user accounts and related store data.

List users

requires authentication

Return a paginated list of users with their stores eager-loaded.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/users?page=1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/users"
);

const params = {
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/users';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "type": "user",
            "id": "51",
            "attributes": {
                "name": "Morgan Hirthe",
                "email": "dare.emelie@example.com"
            },
            "relationships": {
                "store": {
                    "data": {
                        "id": "47",
                        "type": "store"
                    },
                    "links": {
                        "self": "https://dokio.shop/api/v1/users?51"
                    }
                }
            },
            "included": {
                "type": "store",
                "id": 47,
                "attributes": {
                    "name": "Prof. Mina Bauch",
                    "slug": "prof-mina-bauch",
                    "industry": "fashion",
                    "logo": "https://dokio.shop/storage/https://via.placeholder.com/640x480.png/002222?text=nostrum",
                    "color": "#007bff",
                    "createdAt": "2026-09-21T17:28:48.000000Z",
                    "updatedAt": "2026-09-21T17:28:48.000000Z"
                },
                "relationships": {
                    "user": {
                        "data": {
                            "id": 51,
                            "type": "user"
                        },
                        "links": {
                            "self": "https://dokio.shop/api/v1/users/47"
                        }
                    }
                },
                "links": {
                    "self": "https://dokio.shop/api/v1/users/47"
                }
            },
            "links": {
                "self": "https://dokio.shop/api/v1/users/51"
            }
        },
        {
            "type": "user",
            "id": "52",
            "attributes": {
                "name": "Carey Smitham",
                "email": "sleffler@example.org"
            },
            "relationships": {
                "store": {
                    "data": {
                        "id": "48",
                        "type": "store"
                    },
                    "links": {
                        "self": "https://dokio.shop/api/v1/users?52"
                    }
                }
            },
            "included": {
                "type": "store",
                "id": 48,
                "attributes": {
                    "name": "Matilda Feeney",
                    "slug": "matilda-feeney",
                    "industry": "food",
                    "logo": "https://dokio.shop/storage/https://via.placeholder.com/640x480.png/0088cc?text=laboriosam",
                    "color": "#007bff",
                    "createdAt": "2026-09-21T17:28:48.000000Z",
                    "updatedAt": "2026-09-21T17:28:48.000000Z"
                },
                "relationships": {
                    "user": {
                        "data": {
                            "id": 52,
                            "type": "user"
                        },
                        "links": {
                            "self": "https://dokio.shop/api/v1/users/48"
                        }
                    }
                },
                "links": {
                    "self": "https://dokio.shop/api/v1/users/48"
                }
            },
            "links": {
                "self": "https://dokio.shop/api/v1/users/52"
            }
        }
    ],
    "links": {
        "first": "/?page=1",
        "last": "/?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "page": null,
                "active": false
            },
            {
                "url": "/?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "page": null,
                "active": false
            }
        ],
        "path": "/",
        "per_page": 15,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/v1/users

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

page   integer  optional    

Page number for pagination. Example: 1

Get user

requires authentication

Return a single user by ID, including their store.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/users/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/users/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/users/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "type": "user",
        "id": "53",
        "attributes": {
            "name": "Morgan Hirthe",
            "email": "imclaughlin@example.org",
            "createdAt": "2026-09-21T17:28:48.000000Z",
            "updatedAt": "2026-09-21T17:28:48.000000Z",
            "emailVerifiedAt": "2026-09-21T17:28:48.000000Z"
        },
        "relationships": {
            "store": {
                "data": {
                    "id": "49",
                    "type": "store"
                },
                "links": {
                    "self": "http://dokio.shop/api/v1/users?53"
                }
            }
        },
        "included": {
            "type": "store",
            "id": 49,
            "attributes": {
                "name": "Mr. Oswald Koch",
                "slug": "mr-oswald-koch",
                "industry": "home",
                "logo": "http://dokio.shop/storage/https://via.placeholder.com/640x480.png/00ee77?text=consequatur",
                "color": "#007bff",
                "createdAt": "2026-09-21T17:28:48.000000Z",
                "updatedAt": "2026-09-21T17:28:48.000000Z"
            },
            "relationships": {
                "user": {
                    "data": {
                        "id": 53,
                        "type": "user"
                    },
                    "links": {
                        "self": "http://dokio.shop/api/v1/users/49"
                    }
                }
            },
            "links": {
                "self": "http://dokio.shop/api/v1/users/49"
            }
        },
        "links": {
            "self": "http://dokio.shop/api/v1/users/53"
        }
    }
}
 

Request      

GET api/v1/users/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the user. Example: 1

user   integer     

The user ID. Example: 1

Stores

Create and manage vendor stores.

Create store

requires authentication

Create a store for the authenticated user. Accepts multipart/form-data when uploading a logo.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/stores" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=Acme Fashion"\
    --form "industry=fashion"\
    --form "color=b"\
    --form "logo=@/tmp/phpp74ko6sjdmtodAnmsmy" 
const url = new URL(
    "https://dokio.shop/api/v1/stores"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'Acme Fashion');
body.append('industry', 'fashion');
body.append('color', 'b');
body.append('logo', document.querySelector('input[name="logo"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'Acme Fashion'
            ],
            [
                'name' => 'industry',
                'contents' => 'fashion'
            ],
            [
                'name' => 'color',
                'contents' => 'b'
            ],
            [
                'name' => 'logo',
                'contents' => fopen('/tmp/phpp74ko6sjdmtodAnmsmy', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Store created successfully",
    "data": {
        "type": "store",
        "id": 1,
        "attributes": {
            "name": "Acme Fashion",
            "slug": "acme-fashion",
            "industry": "fashion",
            "logo": null,
            "color": "#007bff"
        }
    }
}
 

Request      

POST api/v1/stores

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

Body Parameters

name   string     

The store display name. Must not be greater than 255 characters. Example: Acme Fashion

industry   string     

Store industry. Allowed: fashion, electronics, food, beauty, home, other. Example: fashion

Must be one of:
  • fashion
  • electronics
  • food
  • beauty
  • home
  • other
logo   file  optional    

Optional store logo (jpeg, png, jpg, gif, or svg; max 2MB). Raster logos have whitespace trimmed with GD. SVG uploads are sanitized and their viewBox is tightened around artwork (full-canvas backgrounds ignored); they remain SVG. Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/phpp74ko6sjdmtodAnmsmy

color   string     

Must not be greater than 255 characters. Example: b

Update store

requires authentication

Update an existing store. Accepts multipart/form-data when uploading a new logo.

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/stores/backs" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=Acme Fashion"\
    --form "industry=fashion"\
    --form "color=b"\
    --form "logo=@/tmp/php09ftttgf93n38x1x9oh" 
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'Acme Fashion');
body.append('industry', 'fashion');
body.append('color', 'b');
body.append('logo', document.querySelector('input[name="logo"]').files[0]);

fetch(url, {
    method: "PUT",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'Acme Fashion'
            ],
            [
                'name' => 'industry',
                'contents' => 'fashion'
            ],
            [
                'name' => 'color',
                'contents' => 'b'
            ],
            [
                'name' => 'logo',
                'contents' => fopen('/tmp/php09ftttgf93n38x1x9oh', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Store updated successfully",
    "data": {
        "type": "store",
        "id": 1,
        "attributes": {
            "name": "Acme Fashion",
            "slug": "acme-fashion",
            "industry": "fashion",
            "color": "#007bff"
        }
    }
}
 

Request      

PUT api/v1/stores/{slug}

PATCH api/v1/stores/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the store. Example: backs

store   integer     

The store ID. Example: 1

Body Parameters

name   string     

The store display name. Must not be greater than 255 characters. Example: Acme Fashion

industry   string     

Store industry. Allowed: fashion, electronics, food, beauty, home, other. Example: fashion

Must be one of:
  • fashion
  • electronics
  • food
  • beauty
  • home
  • other
logo   file  optional    

Optional new store logo (jpeg, png, jpg, gif, or svg; max 2MB). Replaces the existing logo. Raster logos have whitespace trimmed with GD. SVG uploads are sanitized and their viewBox is tightened around artwork (full-canvas backgrounds ignored); they remain SVG. Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/php09ftttgf93n38x1x9oh

color   string     

Must not be greater than 255 characters. Example: b

Delete store

requires authentication

Remove a store when it has no related catalog data or orders.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/stores/backs" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Store deleted successfully",
    "data": {
        "type": "store",
        "id": 1,
        "attributes": {
            "name": "Acme Fashion",
            "slug": "acme-fashion"
        }
    }
}
 

Example response (403):


{
    "errors": [
        {
            "status": "403",
            "code": "store.forbidden",
            "detail": "You are not authorized to delete this store"
        }
    ]
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "store.has_related_records",
            "detail": "Cannot delete store because it has related products, categories, options, or orders"
        }
    ]
}
 

Request      

DELETE api/v1/stores/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the store. Example: backs

store   integer     

The store ID. Example: 1

Get store

Return a single store by ID. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "type": "store",
        "id": 50,
        "attributes": {
            "name": "Morgan Hirthe",
            "slug": "morgan-hirthe",
            "industry": "fashion",
            "logo": "http://dokio.shop/storage/https://via.placeholder.com/640x480.png/0077ff?text=qui",
            "color": "#007bff",
            "createdAt": "2026-09-21T17:28:48.000000Z",
            "updatedAt": "2026-09-21T17:28:48.000000Z"
        },
        "relationships": {
            "user": {
                "data": {
                    "id": 54,
                    "type": "user"
                },
                "links": {
                    "self": "http://dokio.shop/api/v1/users/50"
                }
            }
        },
        "links": {
            "self": "http://dokio.shop/api/v1/users/50"
        }
    }
}
 

Request      

GET api/v1/stores/{slug}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the store. Example: backs

store   integer     

The store ID. Example: 1

Get user's store

Return the store associated with a user. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/users/1/store" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/users/1/store"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/users/1/store';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "type": "store",
            "id": 51,
            "attributes": {
                "name": "Rowan Gulgowski",
                "slug": "rowan-gulgowski",
                "industry": "beauty",
                "logo": "http://dokio.shop/storage/https://via.placeholder.com/640x480.png/00bb11?text=sunt",
                "color": "#007bff",
                "createdAt": "2026-09-21T17:28:49.000000Z",
                "updatedAt": "2026-09-21T17:28:49.000000Z"
            },
            "relationships": {
                "user": {
                    "data": {
                        "id": 55,
                        "type": "user"
                    },
                    "links": {
                        "self": "http://dokio.shop/api/v1/users/51"
                    }
                }
            },
            "links": {
                "self": "http://dokio.shop/api/v1/users/51"
            }
        },
        {
            "type": "store",
            "id": 52,
            "attributes": {
                "name": "Mr. Gilbert Swift V",
                "slug": "mr-gilbert-swift-v",
                "industry": "fashion",
                "logo": "http://dokio.shop/storage/https://via.placeholder.com/640x480.png/005500?text=quidem",
                "color": "#007bff",
                "createdAt": "2026-09-21T17:28:49.000000Z",
                "updatedAt": "2026-09-21T17:28:49.000000Z"
            },
            "relationships": {
                "user": {
                    "data": {
                        "id": 56,
                        "type": "user"
                    },
                    "links": {
                        "self": "http://dokio.shop/api/v1/users/52"
                    }
                }
            },
            "links": {
                "self": "http://dokio.shop/api/v1/users/52"
            }
        }
    ]
}
 

Request      

GET api/v1/users/{id}/store

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the user. Example: 1

user   integer     

The user ID. Example: 1

Products

Browse and manage marketplace products.

List store products

Return all products belonging to a store. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs/products" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/products"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/products';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Products retrieved successfully",
    "data": [
        {
            "type": "product",
            "id": 1,
            "attributes": {
                "name": "Classic Tee",
                "price": "29.99",
                "image": "https://api.dokio.local/storage/product/tee.jpg",
                "status": "in stock"
            },
            "relationships": {
                "product_variants": {
                    "data": {
                        "id": 1,
                        "type": "product_variant"
                    }
                }
            },
            "links": {
                "self": "https://api.example.com/products/1"
            }
        }
    ]
}
 

Request      

GET api/v1/stores/{store_slug}/products

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

store   integer     

The store ID. Example: 1

Get a store product

Return a single product belonging to a store. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs/products/sds" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/products/sds"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/products/sds';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product retrieved successfully",
    "data": {
        "type": "product",
        "id": 1,
        "attributes": {
            "name": "Classic Tee",
            "slug": "classic-tee",
            "description_html": "<p>Soft cotton t-shirt in classic fit.</p>"
        },
        "relationships": {
            "product_variants": {
                "data": {
                    "id": 1,
                    "type": "product_variant"
                }
            }
        },
        "includes": {
            "product_variants": {
                "data": {
                    "id": 1,
                    "type": "product_variant",
                    "attributes": {
                        "price": "29.99",
                        "stock": 100,
                        "sku": "TSHIRT-BLUE-M",
                        "image": "https://api.dokio.local/storage/product/tee.jpg",
                        "status": "in stock"
                    }
                }
            }
        },
        "links": {
            "self": "https://api.example.com/products/1"
        }
    }
}
 

Request      

GET api/v1/stores/{store_slug}/products/{slug}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

slug   string     

The slug of the product. Example: sds

store   string     

The store slug. Example: acme-fashion

product   string     

The product slug. Example: classic-tee

List products

requires authentication

Return a paginated list of products. Supports filtering by status, search, dates, and includes.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/products?status=active&search=%2Ashirt%2A&createdAt=2024-01-01&updatedAt=2024-01-01%2C2024-12-31&include=product_variants&page=1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/products"
);

const params = {
    "status": "active",
    "search": "*shirt*",
    "createdAt": "2024-01-01",
    "updatedAt": "2024-01-01,2024-12-31",
    "include": "product_variants",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/products';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'status' => 'active',
            'search' => '*shirt*',
            'createdAt' => '2024-01-01',
            'updatedAt' => '2024-01-01,2024-12-31',
            'include' => 'product_variants',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Paginated products):


{
    "status": 200,
    "message": "Products retrieved successfully",
    "data": [
        {
            "type": "product",
            "id": 1,
            "attributes": {
                "name": "Classic Tee",
                "slug": "classic-tee",
                "createdAt": "2024-01-15T10:00:00.000000Z",
                "updatedAt": "2024-01-15T10:00:00.000000Z",
                "status": "in stock"
            },
            "relationships": {
                "user": {
                    "data": {
                        "id": 1,
                        "type": "user"
                    }
                }
            },
            "links": {
                "self": "https://api.dokio.local/api/v1/products/1"
            }
        }
    ]
}
 

Request      

GET api/v1/products

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

status   string  optional    

Filter by status. Comma-separated for multiple values. Example: active

search   string  optional    

Search product name. Use * as a wildcard (e.g. *shirt*). Example: *shirt*

createdAt   string  optional    

Filter by created date (Y-m-d) or range (start,end). Example: 2024-01-01

updatedAt   string  optional    

Filter by updated date (Y-m-d) or range (start,end). Example: 2024-01-01,2024-12-31

include   string  optional    

Eager-load relations (e.g. product_variants). Example: product_variants

page   integer  optional    

Page number for pagination. Example: 1

Create product

requires authentication

Create a product for the authenticated user's store. Send required description_html (max 100,000 UTF-8 bytes). HTML is sanitized. Mutation responses omit it; fetch a detail route to read it.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/products" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Classic Tee\",
    \"description_html\": \"<h2>تفاصيل المنتج<\\/h2><p>قطن ناعم — <strong>Soft cotton<\\/strong>.<\\/p>\",
    \"category_id\": 1
}"
const url = new URL(
    "https://dokio.shop/api/v1/products"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Classic Tee",
    "description_html": "<h2>تفاصيل المنتج<\/h2><p>قطن ناعم — <strong>Soft cotton<\/strong>.<\/p>",
    "category_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/products';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Classic Tee',
            'description_html' => '<h2>تفاصيل المنتج</h2><p>قطن ناعم — <strong>Soft cotton</strong>.</p>',
            'category_id' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Product created successfully",
    "data": {
        "type": "product",
        "id": 1,
        "attributes": {
            "name": "Classic Tee",
            "slug": "classic-tee",
            "createdAt": "2024-01-15T10:00:00.000000Z",
            "updatedAt": "2024-01-15T10:00:00.000000Z",
            "status": null
        }
    }
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "validation.max_utf8_bytes",
            "detail": "This field exceeds the maximum allowed value.",
            "source": {
                "pointer": "/description_html"
            },
            "meta": {
                "field": "description_html"
            }
        }
    ]
}
 

Request      

POST api/v1/products

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

name   string     

The product name. Must not be greater than 255 characters. Example: Classic Tee

description_html   string     

Required canonical HTML description. Sanitized against the product allowlist. Maximum 100,000 UTF-8 bytes. Example: <h2>تفاصيل المنتج</h2><p>قطن ناعم — <strong>Soft cotton</strong>.</p>

category_id   string     

ID of a category owned by the authenticated user's store. Example: 1

Get product

requires authentication

Return a single product. Pass include=author to embed the owning user.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/products/sds?include=author" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/products/sds"
);

const params = {
    "include": "author",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/products/sds';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'include' => 'author',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "type": "product",
    "id": 1,
    "attributes": {
        "name": "Classic Tee",
        "slug": "classic-tee",
        "description_html": "<p>Soft cotton t-shirt in classic fit.</p>",
        "createdAt": "2024-01-15T10:00:00.000000Z",
        "updatedAt": "2024-01-15T10:00:00.000000Z"
    },
    "relationships": {
        "user": {
            "data": {
                "id": 1,
                "type": "user"
            }
        },
        "category": {
            "data": {
                "id": 1,
                "type": "category"
            }
        },
        "variants": {
            "data": [
                {
                    "id": 1,
                    "type": "variant"
                },
                {
                    "id": 2,
                    "type": "variant"
                }
            ]
        }
    },
    "links": {
        "self": "https://api.dokio.local/api/v1/products/1"
    }
}
 

Request      

GET api/v1/products/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the product. Example: sds

product   string     

The product slug. Example: classic-tee

Query Parameters

include   string  optional    

Optional related resources to include. Use author for the product owner. Example: author

Update product

requires authentication

Replace name, HTML description, and category of an owned product identified by slug. Send required description_html (max 100,000 UTF-8 bytes). HTML is sanitized. Mutation responses omit it; fetch a detail route to read it. Dashboard clients may POST multipart with _method=PUT.

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/products/sds" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Classic Tee\",
    \"description_html\": \"<h2>تفاصيل المنتج<\\/h2><p>قطن ناعم — <strong>Soft cotton<\\/strong>.<\\/p>\",
    \"category_id\": 1
}"
const url = new URL(
    "https://dokio.shop/api/v1/products/sds"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Classic Tee",
    "description_html": "<h2>تفاصيل المنتج<\/h2><p>قطن ناعم — <strong>Soft cotton<\/strong>.<\/p>",
    "category_id": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/products/sds';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Classic Tee',
            'description_html' => '<h2>تفاصيل المنتج</h2><p>قطن ناعم — <strong>Soft cotton</strong>.</p>',
            'category_id' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product updated successfully",
    "data": {
        "type": "product",
        "id": 1,
        "attributes": {
            "name": "Classic Tee",
            "slug": "classic-tee",
            "createdAt": "2024-01-15T10:00:00.000000Z",
            "updatedAt": "2024-01-15T10:00:00.000000Z",
            "status": null
        }
    }
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "validation.max_utf8_bytes",
            "detail": "This field exceeds the maximum allowed value.",
            "source": {
                "pointer": "/description_html"
            },
            "meta": {
                "field": "description_html"
            }
        }
    ]
}
 

Request      

PUT api/v1/products/{slug}

PATCH api/v1/products/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the product. Example: sds

product   string     

The product slug. Example: classic-tee

Body Parameters

name   string     

The product name. Must not be greater than 255 characters. Example: Classic Tee

description_html   string     

Required canonical HTML description. Sanitized against the product allowlist. Maximum 100,000 UTF-8 bytes. Example: <h2>تفاصيل المنتج</h2><p>قطن ناعم — <strong>Soft cotton</strong>.</p>

category_id   string     

ID of a category owned by the authenticated user's store. Example: 1

Delete product

requires authentication

Remove a product when it has no related variants.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/products/sds" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/products/sds"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/products/sds';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product deleted successfully",
    "data": {
        "type": "product",
        "id": 1,
        "attributes": {
            "name": "Classic Tee",
            "slug": "classic-tee"
        }
    }
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "product.has_variants",
            "detail": "Cannot delete product because it has related variants"
        }
    ]
}
 

Request      

DELETE api/v1/products/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the product. Example: sds

product   string     

The product slug. Example: classic-tee

Categories

Manage product categories.

List store categories

Return all categories belonging to a store. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs/categories" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/categories"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/categories';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Categories retrieved successfully",
    "data": [
        {
            "type": "category",
            "id": 1,
            "attributes": {
                "name": "Apparel",
                "slug": "apparel",
                "image": "https://api.dokio.local/storage/category/apparel.jpg",
                "status": "active"
            }
        }
    ],
    "relationships": {
        "store": {
            "data": {
                "id": 1,
                "type": "store"
            },
            "links": {
                "self": "https://api.dokio.local/api/v1/stores/1"
            }
        }
    }
}
 

Request      

GET api/v1/stores/{store_slug}/categories

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

store   string     

The store slug. Example: acme-fashion

Get a store category

Return a single category belonging to a store. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs/categories/backpacks?include=products" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/categories/backpacks"
);

const params = {
    "include": "products",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/categories/backpacks';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'include' => 'products',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Category retrieved successfully",
    "data": {
        "type": "category",
        "id": 1,
        "attributes": {
            "name": "Apparel",
            "slug": "apparel",
            "image": "https://api.dokio.local/storage/category/apparel.jpg",
            "status": "active"
        }
    },
    "relationships": {
        "store": {
            "data": {
                "id": 1,
                "type": "store"
            }
        },
        "links": {
            "self": "https://api.dokio.local/api/v1/stores/1/categories/1"
        }
    }
}
 

Request      

GET api/v1/stores/{store_slug}/categories/{slug}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

slug   string     

The slug of the category. Example: backpacks

The store slug.   string     

Example: acme-fashion

The category slug.   string     

Example: apparel

Query Parameters

include   string  optional    

Optional related resources to include. Use products for the category products to be included. Example: products

List categories

requires authentication

Return all categories.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/categories" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/categories"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/categories';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Categories retrieved successfully",
    "data": [
        {
            "type": "category",
            "id": 1,
            "attributes": {
                "name": "Apparel",
                "slug": "apparel",
                "image": "https://api.dokio.local/storage/category/apparel.jpg",
                "status": "active"
            }
        }
    ]
}
 

Request      

GET api/v1/categories

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create category

requires authentication

Create a new category. Accepts multipart/form-data when uploading an image.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/categories" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=Apparel"\
    --form "image=@/tmp/phpp7h17smqr4npdcs1pPH" 
const url = new URL(
    "https://dokio.shop/api/v1/categories"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'Apparel');
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/categories';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'Apparel'
            ],
            [
                'name' => 'image',
                'contents' => fopen('/tmp/phpp7h17smqr4npdcs1pPH', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Category created successfully",
    "data": {
        "type": "category",
        "id": 1,
        "attributes": {
            "name": "Apparel",
            "slug": "apparel",
            "status": "active"
        }
    }
}
 

Example response (403):


{
    "errors": [
        {
            "status": "403",
            "code": "store.required",
            "detail": "User must have a store to create a category."
        }
    ]
}
 

Request      

POST api/v1/categories

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

Body Parameters

name   string     

The category name. Must not be greater than 255 characters. Example: Apparel

image   file     

Category image file (jpeg, png, jpg, gif, or svg; max 2MB). SVG uploads are sanitized before storage. Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/phpp7h17smqr4npdcs1pPH

Get category

requires authentication

Return a single category by ID.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/categories/backpacks" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/categories/backpacks"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/categories/backpacks';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Category retrieved successfully",
    "data": {
        "type": "category",
        "id": 1,
        "attributes": {
            "name": "Apparel",
            "slug": "apparel",
            "status": "active"
        }
    }
}
 

Request      

GET api/v1/categories/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the category. Example: backpacks

category   integer     

The category ID. Example: 1

Update category

requires authentication

Update an existing category. Accepts multipart/form-data when uploading a new image.

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/categories/backpacks" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "name=Apparel"\
    --form "status=active"\
    --form "image=@/tmp/phpci1fbq17f6f80vHMGY6" 
const url = new URL(
    "https://dokio.shop/api/v1/categories/backpacks"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'Apparel');
body.append('status', 'active');
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "PUT",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/categories/backpacks';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'Apparel'
            ],
            [
                'name' => 'status',
                'contents' => 'active'
            ],
            [
                'name' => 'image',
                'contents' => fopen('/tmp/phpci1fbq17f6f80vHMGY6', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Category updated successfully",
    "data": {
        "type": "category",
        "id": 1,
        "attributes": {
            "name": "Apparel",
            "slug": "apparel",
            "status": "active"
        }
    }
}
 

Request      

PUT api/v1/categories/{slug}

PATCH api/v1/categories/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the category. Example: backpacks

category   integer     

The category ID. Example: 1

Body Parameters

name   string     

The category name. Must not be greater than 255 characters. Example: Apparel

image   file  optional    

Optional new category image (jpeg, png, jpg, gif, or svg; max 2MB). SVG uploads are sanitized before storage. Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/phpci1fbq17f6f80vHMGY6

status   string     

Category status. Example: active

Must be one of:
  • active
  • inactive

Delete category

requires authentication

Remove a category when it has no related products.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/categories/backpacks" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/categories/backpacks"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/categories/backpacks';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Category deleted successfully",
    "data": {
        "type": "category",
        "id": 1,
        "attributes": {
            "name": "Apparel",
            "slug": "apparel",
            "status": "active"
        }
    }
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "category.has_products",
            "detail": "Cannot delete category because it has related products"
        }
    ]
}
 

Request      

DELETE api/v1/categories/{slug}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

slug   string     

The slug of the category. Example: backpacks

category   integer     

The category ID. Example: 1

Enums

Lookup values used by other endpoints (e.g. store industries).

List industries

Return the allowed industry values for store creation and updates. This endpoint is public.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/enums/industries" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/enums/industries"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/enums/industries';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        "fashion",
        "electronics",
        "food",
        "beauty",
        "home",
        "other"
    ]
}
 

Request      

GET api/v1/enums/industries

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

Checkout

Guest COD checkout.

Place COD order

Create a cash-on-delivery order from line items. No cart is stored on the server.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/stores/backs/checkout" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Jane Doe\",
    \"email\": \"jane@example.com\",
    \"phone\": \"01001234567\",
    \"line1\": \"12 Nile Street\",
    \"city\": \"Cairo\",
    \"governorate\": \"Cairo\",
    \"postal_code\": \"11511\",
    \"country\": \"EG\",
    \"items\": [
        {
            \"product_variant_id\": 1,
            \"quantity\": 2
        }
    ]
}"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/checkout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "01001234567",
    "line1": "12 Nile Street",
    "city": "Cairo",
    "governorate": "Cairo",
    "postal_code": "11511",
    "country": "EG",
    "items": [
        {
            "product_variant_id": 1,
            "quantity": 2
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Jane Doe',
            'email' => 'jane@example.com',
            'phone' => '01001234567',
            'line1' => '12 Nile Street',
            'city' => 'Cairo',
            'governorate' => 'Cairo',
            'postal_code' => '11511',
            'country' => 'EG',
            'items' => [
                [
                    'product_variant_id' => 1,
                    'quantity' => 2,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Order placed successfully",
    "data": {
        "type": "order",
        "id": 1,
        "attributes": {
            "number": "01HXYZ",
            "guest_name": "Jane Doe",
            "guest_email": "jane@example.com",
            "guest_phone": "01001234567",
            "status": "pending",
            "subtotal": 200,
            "shipping_amount": 0,
            "total": 200
        }
    }
}
 

Example response (422, Validation failed (empty items, inactive variant, insufficient stock, or foreign-store variant).):


{
    "errors": [
        {
            "status": "422",
            "code": "validation.insufficient_stock",
            "detail": "The submitted value is invalid.",
            "meta": {
                "field": "items"
            }
        }
    ]
}
 

Request      

POST api/v1/stores/{store_slug}/checkout

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

store   string     

Store slug or id. Example: my-store

Body Parameters

name   string     

Guest full name. Must not be greater than 255 characters. Example: Jane Doe

email   string     

Guest email used for order tracking. Must be a valid email address. Must not be greater than 255 characters. Example: jane@example.com

phone   string     

Guest phone number for COD delivery. Must not be greater than 50 characters. Example: 01001234567

line1   string     

Shipping street address. Must not be greater than 255 characters. Example: 12 Nile Street

city   string     

Shipping city. Must not be greater than 100 characters. Example: Cairo

governorate   string     

Shipping governorate / state. Must not be greater than 100 characters. Example: Cairo

postal_code   string  optional    

Optional postal code. Must not be greater than 20 characters. Example: 11511

country   string  optional    

ISO 3166-1 alpha-2 country code. Defaults to EG. Must not be greater than 255 characters. Example: EG

items   object[]     

Line items to purchase. Duplicate variant ids are merged by summing quantities. Must have at least 1 items.

product_variant_id   integer     

Sellable product variant id. The id of an existing record in the product_variants table. Example: 1

quantity   integer     

Quantity to order for this variant. Must be at least 1. Example: 2

Endpoints

List product option values

requires authentication

Return all product option values.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-options/1/product-option-values" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-options/1/product-option-values"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options/1/product-option-values';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product option values retrieved successfully",
    "data": [
        {
            "type": "product_option_value",
            "id": 1,
            "attributes": {
                "value": "Small",
                "product_option_id": 1
            },
            "relationships": {
                "product_option": {
                    "data": {
                        "id": 1,
                        "type": "product_option"
                    }
                }
            },
            "links": {
                "self": "https://api.example.com/product-option-values/1"
            }
        }
    ]
}
 

Request      

GET api/v1/product-options/{productOption_id}/product-option-values

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

productOption_id   integer     

The ID of the productOption. Example: 1

Create product option values

requires authentication

Create multiple product option values for the same option.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/product-option-values" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"product_option_id\": \"architecto\",
    \"values\": [
        \"n\"
    ]
}"
const url = new URL(
    "https://dokio.shop/api/v1/product-option-values"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "product_option_id": "architecto",
    "values": [
        "n"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-option-values';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'product_option_id' => 'architecto',
            'values' => [
                'n',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Product option values created successfully",
    "data": [
        {
            "type": "product_option_value",
            "id": 1,
            "attributes": {
                "value": "Small",
                "product_option_id": 1
            },
            "relationships": {
                "product_option": {
                    "type": "product_option",
                    "id": 1
                }
            },
            "links": {
                "self": "https://api.dokio.local/api/v1/product-option-values/1"
            }
        }
    ]
}
 

Request      

POST api/v1/product-option-values

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

product_option_id   string     

The id of an existing record in the product_options table. Example: architecto

values   string[]     

Must not be greater than 255 characters.

Display the specified resource.

requires authentication

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-option-values/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-option-values/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-option-values/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

GET api/v1/product-option-values/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option value. Example: 1

Update the specified resource in storage.

requires authentication

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/product-option-values/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-option-values/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-option-values/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/v1/product-option-values/{id}

PATCH api/v1/product-option-values/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option value. Example: 1

Delete product option value

requires authentication

Remove a product option value when it has no related variants.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/product-option-values/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-option-values/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-option-values/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product option value deleted successfully",
    "data": {
        "type": "product_option_value",
        "id": 1,
        "attributes": {
            "value": "Small",
            "product_option_id": 1
        }
    }
}
 

Example response (403):


{
    "errors": [
        {
            "status": "403",
            "code": "product_option_value.forbidden",
            "detail": "You are not authorized to delete this product option value"
        }
    ]
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "product_option_value.has_variants",
            "detail": "Cannot delete product option value because it has related variants"
        }
    ]
}
 

Request      

DELETE api/v1/product-option-values/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option value. Example: 1

Orders

Vendor order management.

List orders

requires authentication

Return orders for the authenticated vendor store.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/orders" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/orders"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/orders';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Orders retrieved successfully",
    "data": [
        {
            "type": "order",
            "id": 1,
            "attributes": {
                "number": "01HXYZ",
                "status": "pending",
                "total": 200
            }
        }
    ]
}
 

Request      

GET api/v1/orders

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Show order

requires authentication

Return a single store order.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/orders/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/orders/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/orders/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Order retrieved successfully",
    "data": {
        "type": "order",
        "id": 1,
        "attributes": {
            "number": "01HXYZ",
            "status": "pending",
            "total": 200
        }
    }
}
 

Request      

GET api/v1/orders/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the order. Example: 1

order   integer     

Order id. Example: 1

Update order

requires authentication

Update order, payment, and/or shipment status.

Example request:
curl --request PATCH \
    "https://dokio.shop/api/v1/orders/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"status\": \"confirmed\",
    \"payment_status\": \"paid\",
    \"shipment_status\": \"shipped\"
}"
const url = new URL(
    "https://dokio.shop/api/v1/orders/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": "confirmed",
    "payment_status": "paid",
    "shipment_status": "shipped"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/orders/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'status' => 'confirmed',
            'payment_status' => 'paid',
            'shipment_status' => 'shipped',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Order updated successfully",
    "data": {
        "type": "order",
        "id": 1,
        "attributes": {
            "number": "01HXYZ",
            "status": "confirmed",
            "total": 200
        }
    }
}
 

Request      

PATCH api/v1/orders/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the order. Example: 1

order   integer     

Order id. Example: 1

Body Parameters

status   string  optional    

Order status. Allowed: pending, confirmed, cancelled, completed. Example: confirmed

Must be one of:
  • pending
  • confirmed
  • cancelled
  • completed
payment_status   string  optional    

Payment status. Allowed: unpaid, paid. Example: paid

Must be one of:
  • unpaid
  • paid
shipment_status   string  optional    

Shipment status. Allowed: pending, shipped, delivered, cancelled. Example: shipped

Must be one of:
  • pending
  • shipped
  • delivered
  • cancelled

Track guest order

Look up an order by public number and guest email.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/orders/01HXYZ?email=jane%40example.com" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"gbailey@example.net\"
}"
const url = new URL(
    "https://dokio.shop/api/v1/orders/01HXYZ"
);

const params = {
    "email": "jane@example.com",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "gbailey@example.net"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/orders/01HXYZ';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'email' => 'jane@example.com',
        ],
        'json' => [
            'email' => 'gbailey@example.net',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Order retrieved successfully",
    "data": {
        "type": "order",
        "id": 1,
        "attributes": {
            "number": "01HXYZ",
            "status": "pending",
            "total": 200
        }
    }
}
 

Example response (404):


{
    "status": 404,
    "message": "Order not found"
}
 

Request      

GET api/v1/orders/{number}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

number   string     

Public order number returned at checkout. Example: 01HXYZ

Query Parameters

email   string     

Guest email used when placing the order. Example: jane@example.com

Body Parameters

email   string     

Must be a valid email address. Example: gbailey@example.net

Product Options

Manage product options.

List product options

requires authentication

Return all product options.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-options" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-options"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product options retrieved successfully",
    "data": [
        {
            "type": "product_option",
            "id": 1,
            "attributes": {
                "name": "Apparel"
            }
        }
    ]
}
 

Request      

GET api/v1/product-options

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create product option

requires authentication

Create a new product option.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/product-options" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\"
}"
const url = new URL(
    "https://dokio.shop/api/v1/product-options"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'b',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Product option created successfully",
    "data": {
        "type": "product_option",
        "id": 1,
        "attributes": {
            "name": "Size"
        }
    }
}
 

Request      

POST api/v1/product-options

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: b

Display the specified resource.

requires authentication

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-options/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-options/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

GET api/v1/product-options/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option. Example: 1

Update product option

requires authentication

Rename an owned product option. JSON PUT/PATCH and multipart POST with _method=PUT are supported. Identity, store, and related values stay unchanged.

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/product-options/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Size\"
}"
const url = new URL(
    "https://dokio.shop/api/v1/product-options/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Size"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Size',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product option updated successfully",
    "data": {
        "type": "product_option",
        "id": 1,
        "attributes": {
            "name": "Size"
        }
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "validation.required",
            "detail": "This field is required.",
            "meta": {
                "field": "request"
            }
        }
    ]
}
 

Request      

PUT api/v1/product-options/{id}

PATCH api/v1/product-options/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option. Example: 1

productOption   integer     

The product option ID. Example: 1

Body Parameters

name   string  optional    

Non-blank option name, max 255 characters. Must not be greater than 255 characters. Example: Size

store_id   string  optional    

Delete product option

requires authentication

Remove a product option when it has no related values.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/product-options/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-options/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-options/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product option deleted successfully",
    "data": {
        "type": "product_option",
        "id": 1,
        "attributes": {
            "name": "Size"
        }
    }
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "product_option.has_values",
            "detail": "Cannot delete product option because it has related values"
        }
    ]
}
 

Request      

DELETE api/v1/product-options/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product option. Example: 1

Product Variants

Manage product variants.

List product variants

requires authentication

Return all product variants.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-variants" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-variants"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-variants';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product variants retrieved successfully",
    "data": [
        {
            "type": "product_variant",
            "id": 1,
            "attributes": {
                "name": "Small",
                "price": 100,
                "stock": 100,
                "product_id": 1,
                "product_option_id": 1
            },
            "relationships": {
                "product": {
                    "data": {
                        "id": 1,
                        "type": "product"
                    }
                },
                "product_option_value": {
                    "data": {
                        "id": 1,
                        "type": "product_option_value"
                    }
                }
            },
            "links": {
                "self": "https://api.example.com/product-variants/1"
            }
        }
    ]
}
 

Request      

GET api/v1/product-variants

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create product variant

requires authentication

Create a new product variant.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/product-variants" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "price=100"\
    --form "stock=100"\
    --form "product_id=1"\
    --form "product_option_value_id=1"\
    --form "sku=1234567890"\
    --form "status=active"\
    --form "image=@/tmp/phpo6imcnsornmm3QDpxTq" 
const url = new URL(
    "https://dokio.shop/api/v1/product-variants"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('price', '100');
body.append('stock', '100');
body.append('product_id', '1');
body.append('product_option_value_id', '1');
body.append('sku', '1234567890');
body.append('status', 'active');
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-variants';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'price',
                'contents' => '100'
            ],
            [
                'name' => 'stock',
                'contents' => '100'
            ],
            [
                'name' => 'product_id',
                'contents' => '1'
            ],
            [
                'name' => 'product_option_value_id',
                'contents' => '1'
            ],
            [
                'name' => 'sku',
                'contents' => '1234567890'
            ],
            [
                'name' => 'status',
                'contents' => 'active'
            ],
            [
                'name' => 'image',
                'contents' => fopen('/tmp/phpo6imcnsornmm3QDpxTq', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Product variant created successfully",
    "data": {
        "type": "product_variant",
        "id": 1,
        "attributes": {
            "name": "Small",
            "price": 100,
            "stock": 100,
            "product_id": 1,
            "product_option_id": 1
        }
    }
}
 

Request      

POST api/v1/product-variants

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

Body Parameters

price   number     

The price of the product variant. Must be at least 0. Example: 100

stock   integer     

The stock of the product variant. Must be at least 0. Example: 100

product_id   string     

The product ID of the product variant. The id of an existing record in the products table. Example: 1

product_option_value_id   string     

The product option value ID of the product variant. The id of an existing record in the product_option_values table. Example: 1

sku   string     

The SKU of the product variant. Must not be greater than 255 characters. Example: 1234567890

image   file     

The image of the product variant (multipart file upload). Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/phpo6imcnsornmm3QDpxTq

status   string     

The status of the product variant. Example: active

Must be one of:
  • active
  • inactive

Display the specified resource.

requires authentication

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/product-variants/3" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-variants/3"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-variants/3';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

GET api/v1/product-variants/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product variant. Example: 3

Update product variant

requires authentication

Update supplied fields on an owned product variant. JSON PUT/PATCH and multipart POST with _method=PUT are supported. Omitted fields, including the image, remain unchanged.

Example request:
curl --request PUT \
    "https://dokio.shop/api/v1/product-variants/3" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"price\": 12500,
    \"stock\": 8,
    \"sku\": \"TEE-M\",
    \"status\": \"active\",
    \"product_option_value_id\": 1,
    \"product_id\": 1
}"
const url = new URL(
    "https://dokio.shop/api/v1/product-variants/3"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "price": 12500,
    "stock": 8,
    "sku": "TEE-M",
    "status": "active",
    "product_option_value_id": 1,
    "product_id": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-variants/3';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'price' => 12500,
            'stock' => 8,
            'sku' => 'TEE-M',
            'status' => 'active',
            'product_option_value_id' => 1,
            'product_id' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product variant updated successfully",
    "data": {
        "type": "product_variant",
        "id": 1,
        "attributes": {
            "price": 12500,
            "stock": 8,
            "sku": "TEE-M",
            "status": "active",
            "product_id": 1,
            "product_option_value_id": 1
        }
    }
}
 

Example response (401):


{
    "errors": [
        {
            "status": "401",
            "code": "unauthenticated",
            "detail": "Unauthenticated."
        }
    ]
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "validation.required",
            "detail": "This field is required.",
            "meta": {
                "field": "request"
            }
        }
    ]
}
 

Request      

PUT api/v1/product-variants/{id}

PATCH api/v1/product-variants/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product variant. Example: 3

productVariant   integer     

The product variant ID. Example: 1

Body Parameters

price   integer  optional    

Integer minor-unit price from 0 to 2147483647. Omitted value is unchanged. Must be at least 0. Must not be greater than 2147483647. Example: 12500

stock   integer  optional    

Absolute integer stock from 0 to 2147483647. Omitted value is unchanged. Must be at least 0. Must not be greater than 2147483647. Example: 8

sku   string  optional    

Non-blank SKU, max 255 characters. No uniqueness rule is applied. Must not be greater than 255 characters. Example: TEE-M

status   string  optional    

Availability status. Allowed: active, inactive. Example: active

Must be one of:
  • active
  • inactive
image   file  optional    

Replacement image upload (jpeg, png, jpg, gif, or svg; max 2MB). SVG uploads are sanitized. Omitted image is retained; URLs and null are rejected. Must be an image. Must not be greater than 2048 kilobytes.

product_option_value_id   integer  optional    

Replacement option value that belongs to the authenticated store. The id of an existing record in the product_option_values table. Example: 1

product_id   integer  optional    

Optional compatibility echo. Must equal the current product ID and is not persisted as a change. Example: 1

store_id   string  optional    

Delete product variant

requires authentication

Remove a product variant when it is not used in any orders.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/product-variants/3" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/product-variants/3"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/product-variants/3';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Product variant deleted successfully",
    "data": {
        "type": "product_variant",
        "id": 1,
        "attributes": {
            "stock": 100,
            "price": 100
        }
    }
}
 

Example response (403):


{
    "errors": [
        {
            "status": "403",
            "code": "product_variant.forbidden",
            "detail": "You are not authorized to delete this product variant"
        }
    ]
}
 

Example response (422):


{
    "errors": [
        {
            "status": "422",
            "code": "product_variant.used_in_orders",
            "detail": "Cannot delete product variant because it is used in orders"
        }
    ]
}
 

Request      

DELETE api/v1/product-variants/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the product variant. Example: 3

Storefront rows

Public homepage sections for a store.

List public store rows

Return visible homepage sections for a store slug, with slides. Hidden and unknown types are omitted.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/stores/backs/rows" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/stores/backs/rows"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/stores/backs/rows';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Rows retrieved successfully",
    "data": [
        {
            "type": "store_row",
            "id": 12,
            "attributes": {
                "type": "hero_slider",
                "position": 1,
                "isVisible": true,
                "settings": {
                    "autoplay": true,
                    "interval": 5000,
                    "height": "large",
                    "overlay": "dark"
                }
            },
            "includes": {
                "slides": []
            }
        }
    ]
}
 

Request      

GET api/v1/stores/{store_slug}/rows

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

store_slug   string     

The slug of the store. Example: backs

store   string     

The store slug. Example: acme-fashion

List store rows

requires authentication

Return every homepage section for the authenticated merchant store, including hidden rows and slides.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/store/rows" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Rows retrieved successfully",
    "data": [
        {
            "type": "store_row",
            "id": 12,
            "attributes": {
                "type": "hero_slider",
                "position": 1,
                "isVisible": true,
                "settings": {
                    "autoplay": true,
                    "interval": 5000,
                    "height": "large",
                    "overlay": "dark"
                },
                "createdAt": "2026-09-10T00:00:00.000000Z",
                "updatedAt": "2026-09-10T00:00:00.000000Z"
            },
            "relationships": {
                "store": {
                    "data": {
                        "type": "store",
                        "id": 1
                    }
                },
                "slides": {
                    "data": []
                }
            },
            "includes": {
                "slides": []
            }
        }
    ]
}
 

Request      

GET api/v1/store/rows

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Create store row

requires authentication

Append a supported homepage section to the authenticated merchant store.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/store/rows" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"type\": \"banner\",
    \"settings\": {
        \"heading\": \"Summer\",
        \"autoplay\": false,
        \"interval\": 1,
        \"height\": \"medium\",
        \"overlay\": \"dark\",
        \"limit\": 4,
        \"message\": \"g\",
        \"alt\": \"z\",
        \"link\": \"m\",
        \"productIds\": [
            16
        ],
        \"categoryIds\": [
            16
        ]
    }
}"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": "banner",
    "settings": {
        "heading": "Summer",
        "autoplay": false,
        "interval": 1,
        "height": "medium",
        "overlay": "dark",
        "limit": 4,
        "message": "g",
        "alt": "z",
        "link": "m",
        "productIds": [
            16
        ],
        "categoryIds": [
            16
        ]
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'type' => 'banner',
            'settings' => [
                'heading' => 'Summer',
                'autoplay' => false,
                'interval' => 1,
                'height' => 'medium',
                'overlay' => 'dark',
                'limit' => 4,
                'message' => 'g',
                'alt' => 'z',
                'link' => 'm',
                'productIds' => [
                    16,
                ],
                'categoryIds' => [
                    16,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Row created successfully",
    "data": {
        "type": "store_row",
        "id": 19,
        "attributes": {
            "type": "banner",
            "position": 5,
            "isVisible": false,
            "settings": {
                "heading": "Summer",
                "alt": "",
                "link": "/products",
                "image": null
            }
        }
    }
}
 

Request      

POST api/v1/store/rows

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

type   string     

Supported homepage section type. Example: banner

Must be one of:
  • hero_slider
  • featured_products
  • categories
  • welcome_marquee
  • banner
settings   object  optional    

Optional type-specific settings. Omitted keys use defaults.

autoplay   boolean  optional    

Example: false

interval   integer  optional    

Must be at least 2000. Must not be greater than 15000. Example: 1

height   string  optional    

Example: medium

Must be one of:
  • small
  • medium
  • large
overlay   string  optional    

Example: dark

Must be one of:
  • none
  • light
  • dark
limit   integer  optional    

Must be at least 4. Must not be greater than 12. Example: 4

heading   string  optional    

Must not be greater than 80 characters. Example: Summer

message   string  optional    

Must not be greater than 120 characters. Example: g

alt   string  optional    

Must not be greater than 120 characters. Example: z

link   string  optional    

Must not be greater than 2048 characters. Example: m

productIds   integer[]  optional    
categoryIds   integer[]  optional    
image   string  optional    

Reorder store rows

requires authentication

Rewrite every homepage section position for the authenticated store. The body must list every current row exactly once.

Example request:
curl --request PATCH \
    "https://dokio.shop/api/v1/store/rows/reorder" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rows\": [
        {
            \"id\": 12,
            \"position\": 1
        },
        {
            \"id\": 8,
            \"position\": 2
        }
    ]
}"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/reorder"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rows": [
        {
            "id": 12,
            "position": 1
        },
        {
            "id": 8,
            "position": 2
        }
    ]
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/reorder';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'rows' => [
                [
                    'id' => 12,
                    'position' => 1,
                ],
                [
                    'id' => 8,
                    'position' => 2,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Rows reordered successfully",
    "data": []
}
 

Request      

PATCH api/v1/store/rows/reorder

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

rows   object[]     

Every current section exactly once. Positions may be any unique integers; the server stores dense 1..n in array order. Must have at least 1 items.

id   integer     

Example: 16

position   integer     

Example: 16

Update store row

requires authentication

Update visibility or settings for one homepage section. Type cannot change. Banner images are uploaded as image, not as settings.image.

Example request:
curl --request PATCH \
    "https://dokio.shop/api/v1/store/rows/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"is_visible\": true,
    \"settings\": {
        \"heading\": \"Our picks\",
        \"limit\": 8,
        \"productIds\": [
            14,
            9
        ],
        \"autoplay\": true,
        \"interval\": 1,
        \"height\": \"large\",
        \"overlay\": \"dark\",
        \"message\": \"n\",
        \"alt\": \"g\",
        \"link\": \"z\",
        \"categoryIds\": [
            16
        ]
    }
}"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "is_visible": true,
    "settings": {
        "heading": "Our picks",
        "limit": 8,
        "productIds": [
            14,
            9
        ],
        "autoplay": true,
        "interval": 1,
        "height": "large",
        "overlay": "dark",
        "message": "n",
        "alt": "g",
        "link": "z",
        "categoryIds": [
            16
        ]
    }
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'is_visible' => true,
            'settings' => [
                'heading' => 'Our picks',
                'limit' => 8,
                'productIds' => [
                    14,
                    9,
                ],
                'autoplay' => true,
                'interval' => 1,
                'height' => 'large',
                'overlay' => 'dark',
                'message' => 'n',
                'alt' => 'g',
                'link' => 'z',
                'categoryIds' => [
                    16,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Row updated successfully",
    "data": {
        "type": "store_row",
        "id": 12,
        "attributes": {
            "type": "featured_products",
            "isVisible": true,
            "settings": {
                "limit": 8,
                "heading": "Our picks",
                "productIds": [
                    14,
                    9
                ]
            }
        }
    }
}
 

Request      

PATCH api/v1/store/rows/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the row. Example: 1

Body Parameters

type   string  optional    

Rejected on update. Section type is immutable.

is_visible   boolean  optional    

Whether customers should see this section. Example: true

image   file  optional    

Banner image upload. Ignored for other section types. Must be an image. Must not be greater than 2048 kilobytes.

settings   object  optional    

Type-specific settings. Unknown keys are rejected. Do not send settings.image; upload image for banners.

autoplay   boolean  optional    

Example: true

interval   integer  optional    

Must be at least 2000. Must not be greater than 15000. Example: 1

height   string  optional    

Example: large

Must be one of:
  • small
  • medium
  • large
overlay   string  optional    

Example: dark

Must be one of:
  • none
  • light
  • dark
limit   integer  optional    

Must be at least 4. Must not be greater than 12. Example: 8

heading   string  optional    

Must not be greater than 80 characters. Example: Our picks

message   string  optional    

Must not be greater than 120 characters. Example: n

alt   string  optional    

Must not be greater than 120 characters. Example: g

link   string  optional    

Must not be greater than 2048 characters. Example: z

productIds   integer[]  optional    
categoryIds   integer[]  optional    
image   string  optional    

Delete store row

requires authentication

Delete a homepage section, its slides, and unused uploaded images.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/store/rows/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Row deleted successfully",
    "data": []
}
 

Request      

DELETE api/v1/store/rows/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the row. Example: 1

Storefront slides

Manage slides for homepage slider sections.

List slides

requires authentication

Return slides for one homepage section, ordered by position then id.

Example request:
curl --request GET \
    --get "https://dokio.shop/api/v1/store/rows/1/slides" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/1/slides"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/1/slides';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Slides retrieved successfully",
    "data": [
        {
            "type": "store_slide",
            "id": 3,
            "attributes": {
                "position": 1,
                "title": "Summer",
                "subtitle": "Sale",
                "image": "https://api.example.com/storage/store_row/slide.jpg",
                "link": "/products",
                "settings": {
                    "cta_text": "Shop"
                }
            }
        }
    ]
}
 

Request      

GET api/v1/store/rows/{row_id}/slides

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

row_id   integer     

The ID of the row. Example: 1

row   integer     

The homepage section id. Example: 12

Create slide

requires authentication

Add a slide to a slider section. Image is required. Non-slider types return 422.

Example request:
curl --request POST \
    "https://dokio.shop/api/v1/store/rows/1/slides" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "title=Summer"\
    --form "subtitle=Sale"\
    --form "link=/products"\
    --form "cta_text=Shop"\
    --form "settings[cta_text]=b"\
    --form "image=@/tmp/php4fjlcrokq7ml5Y8DOKh" 
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/1/slides"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('title', 'Summer');
body.append('subtitle', 'Sale');
body.append('link', '/products');
body.append('cta_text', 'Shop');
body.append('settings[cta_text]', 'b');
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/1/slides';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'title',
                'contents' => 'Summer'
            ],
            [
                'name' => 'subtitle',
                'contents' => 'Sale'
            ],
            [
                'name' => 'link',
                'contents' => '/products'
            ],
            [
                'name' => 'cta_text',
                'contents' => 'Shop'
            ],
            [
                'name' => 'settings[cta_text]',
                'contents' => 'b'
            ],
            [
                'name' => 'image',
                'contents' => fopen('/tmp/php4fjlcrokq7ml5Y8DOKh', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "status": 201,
    "message": "Slide created successfully",
    "data": {
        "type": "store_slide",
        "id": 3,
        "attributes": {
            "position": 1,
            "title": "Summer",
            "image": "https://api.example.com/storage/store_row/slide.jpg",
            "link": "/products",
            "settings": {
                "cta_text": "Shop"
            }
        }
    }
}
 

Request      

POST api/v1/store/rows/{row_id}/slides

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: multipart/form-data

Accept        

Example: application/json

URL Parameters

row_id   integer     

The ID of the row. Example: 1

row   integer     

The homepage section id. Example: 12

Body Parameters

title   string  optional    

Optional slide title, max 80 characters. Must not be greater than 80 characters. Example: Summer

subtitle   string  optional    

Optional slide subtitle, max 160 characters. Must not be greater than 160 characters. Example: Sale

link   string  optional    

http(s) URL or a single-leading-slash in-store path. Must not be greater than 2048 characters. Example: /products

cta_text   string  optional    

Optional button label, max 40 characters. Must not be greater than 40 characters. Example: Shop

settings   object  optional    
cta_text   string  optional    

Must not be greater than 40 characters. Example: b

image   file     

Required image upload, max 2MB. SVG is sanitized. Must be an image. Must not be greater than 2048 kilobytes. Example: /tmp/php4fjlcrokq7ml5Y8DOKh

Reorder slides

requires authentication

Rewrite every slide position for one section. The body must list every current slide of that row exactly once.

Example request:
curl --request PATCH \
    "https://dokio.shop/api/v1/store/rows/1/slides/reorder" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"slides\": [
        {
            \"id\": 3,
            \"position\": 1
        },
        {
            \"id\": 4,
            \"position\": 2
        }
    ]
}"
const url = new URL(
    "https://dokio.shop/api/v1/store/rows/1/slides/reorder"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "slides": [
        {
            "id": 3,
            "position": 1
        },
        {
            "id": 4,
            "position": 2
        }
    ]
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/rows/1/slides/reorder';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'slides' => [
                [
                    'id' => 3,
                    'position' => 1,
                ],
                [
                    'id' => 4,
                    'position' => 2,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Slides reordered successfully",
    "data": []
}
 

Request      

PATCH api/v1/store/rows/{row_id}/slides/reorder

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

row_id   integer     

The ID of the row. Example: 1

row   integer     

The homepage section id. Example: 12

Body Parameters

slides   object[]     

Every current slide of this section exactly once. The server stores dense 1..n in array order. Must have at least 1 items.

id   integer     

Example: 16

position   integer     

Example: 16

Update slide

requires authentication

Update slide copy or replace its image. Omitted image is kept. Null may clear title, subtitle, link, and cta_text.

Example request:
curl --request PATCH \
    "https://dokio.shop/api/v1/store/slides/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"Updated\",
    \"subtitle\": \"Sale\",
    \"link\": \"\\/products\",
    \"cta_text\": \"Shop\",
    \"settings\": {
        \"cta_text\": \"b\"
    }
}"
const url = new URL(
    "https://dokio.shop/api/v1/store/slides/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "Updated",
    "subtitle": "Sale",
    "link": "\/products",
    "cta_text": "Shop",
    "settings": {
        "cta_text": "b"
    }
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/slides/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'title' => 'Updated',
            'subtitle' => 'Sale',
            'link' => '/products',
            'cta_text' => 'Shop',
            'settings' => [
                'cta_text' => 'b',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Slide updated successfully",
    "data": {
        "type": "store_slide",
        "id": 3,
        "attributes": {
            "title": "Updated",
            "image": "https://api.example.com/storage/store_row/slide.jpg"
        }
    }
}
 

Request      

PATCH api/v1/store/slides/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the slide. Example: 1

slide   integer     

The slide id. Example: 3

Body Parameters

title   string  optional    

Slide title. Null clears it. Must not be greater than 80 characters. Example: Updated

subtitle   string  optional    

Slide subtitle. Null clears it. Must not be greater than 160 characters. Example: Sale

link   string  optional    

http(s) URL or a single-leading-slash in-store path. Null clears it. Must not be greater than 2048 characters. Example: /products

cta_text   string  optional    

Button label. Null clears it. Must not be greater than 40 characters. Example: Shop

settings   object  optional    
cta_text   string  optional    

Must not be greater than 40 characters. Example: b

image   file  optional    

Replacement image. Omit to keep the current file. Null cannot clear image. Must be an image. Must not be greater than 2048 kilobytes.

Delete slide

requires authentication

Delete a slide and its unused image after the record is removed.

Example request:
curl --request DELETE \
    "https://dokio.shop/api/v1/store/slides/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://dokio.shop/api/v1/store/slides/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dokio.shop/api/v1/store/slides/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "status": 200,
    "message": "Slide deleted successfully",
    "data": []
}
 

Request      

DELETE api/v1/store/slides/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the slide. Example: 1

slide   integer     

The slide id. Example: 3