public integration surface

Suplus API

A public HTTPS API for personal automations, GPT Actions, and future assistant clients that need to read or update household supplies.

Base URL
https://suplus.cofficus.club/api/v1
Auth
Bearer API token or browser session
Status
First public version

OpenAPI assistant schema

This GPT Actions schema uses a compact assistant facade with 4 operations: context, search, command, and confirmed destructive command. The full machine-readable API contract is available separately.

{
    "openapi": "3.1.0",
    "info": {
        "title": "Suplus API",
        "version": "1.0.0",
        "description": "GPT Actions-compatible assistant facade. Compact command routes avoid the 30-operation Builder limit."
    },
    "servers": [
        {
            "url": "https://suplus.cofficus.club/api/v1"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "paths": {
        "/assistant/context": {
            "get": {
                "summary": "Get assistant context",
                "operationId": "getAssistantContext",
                "description": "List spaces. With space_id, include rooms, zones, suppliers, and optional shopping, members, or activity.",
                "x-openai-isConsequential": false,
                "parameters": [
                    {
                        "name": "space_id",
                        "in": "query",
                        "required": false,
                        "description": "Optional Space id from this response.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "include_shopping",
                        "in": "query",
                        "required": false,
                        "description": "Include shopping list blocks.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "include_members",
                        "in": "query",
                        "required": false,
                        "description": "Include owner, members, and owner-visible invitations.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "include_activity",
                        "in": "query",
                        "required": false,
                        "description": "Include latest activity events.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "supply_limit",
                        "in": "query",
                        "required": false,
                        "description": "Selected-space supply limit from 1 to 300.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Ok"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/assistant/search": {
            "get": {
                "summary": "Search assistant resources",
                "operationId": "searchAssistantResources",
                "description": "Search accessible supplies, zones, and suppliers. Resolve places before answering location questions.",
                "x-openai-isConsequential": false,
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": true,
                        "description": "Search text.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "space_id",
                        "in": "query",
                        "required": false,
                        "description": "Optional Space id filter.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Result limit from 1 to 50.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Grouped search results.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "query": {
                                            "type": "string"
                                        },
                                        "supplies": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Supply"
                                            }
                                        },
                                        "zones": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Zone"
                                            }
                                        },
                                        "suppliers": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Supplier"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/assistant/command": {
            "post": {
                "summary": "Run assistant command",
                "operationId": "runAssistantCommand",
                "description": "Create, rename, move, invite, resend, or update non-destructive Suplus objects.",
                "x-openai-isConsequential": false,
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AssistantCommand"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Ok"
                    },
                    "201": {
                        "$ref": "#/components/responses/Ok"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        },
        "/assistant/destructive-command": {
            "post": {
                "summary": "Run confirmed delete command",
                "operationId": "runAssistantDestructiveCommand",
                "description": "Delete or remove Suplus objects after explicit user confirmation.",
                "x-openai-isConsequential": true,
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AssistantDestructiveCommand"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Ok"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer"
            }
        },
        "responses": {
            "Ok": {
                "description": "Successful response."
            },
            "NoContent": {
                "description": "Successful empty response."
            },
            "Unauthorized": {
                "description": "Missing, expired, or invalid authentication.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ApiError"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "The authenticated user cannot perform this action.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ApiError"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "Resource was not found or is not accessible.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ApiError"
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "Too many requests.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ApiError"
                        }
                    }
                }
            },
            "ValidationError": {
                "description": "The request body or parameters are invalid.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ValidationApiError"
                        }
                    }
                }
            }
        },
        "schemas": {
            "SpaceKind": {
                "type": "string",
                "enum": [
                    "home",
                    "workspace",
                    "hobby"
                ]
            },
            "AccessLevel": {
                "type": "string",
                "enum": [
                    "full",
                    "limited"
                ]
            },
            "ManualShoppingStatus": {
                "type": "string",
                "enum": [
                    "new",
                    "ordered",
                    "completed"
                ]
            },
            "SpaceSummary": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "kind",
                    "current_user_access"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Database id. Use this exact value as the space path parameter."
                    },
                    "name": {
                        "type": "string"
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "home",
                            "workspace",
                            "hobby"
                        ]
                    },
                    "owner_id": {
                        "type": "integer"
                    },
                    "current_user_access": {
                        "type": "string",
                        "enum": [
                            "owner",
                            "full",
                            "limited"
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Room": {
                "type": "object",
                "required": [
                    "id",
                    "space_id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Database id. Use this exact value as the room path parameter."
                    },
                    "space_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "sort_order": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "is_default": {
                        "type": "boolean"
                    },
                    "is_unsorted": {
                        "type": "boolean"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "SupplyStatus": {
                "type": "string",
                "enum": [
                    "ok",
                    "low",
                    "out",
                    "ordered"
                ]
            },
            "Supply": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "status": {
                        "$ref": "#/components/schemas/SupplyStatus"
                    },
                    "room_id": {
                        "type": "integer"
                    },
                    "zone_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "note": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "room": {
                        "$ref": "#/components/schemas/Room"
                    },
                    "zone": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/Zone"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    }
                }
            },
            "Zone": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "room_id": {
                        "type": "integer"
                    },
                    "sort_order": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "room": {
                        "$ref": "#/components/schemas/Room"
                    }
                }
            },
            "Supplier": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "space_id": {
                        "type": "integer"
                    }
                }
            },
            "SupplyStoreInput": {
                "type": "object",
                "properties": {
                    "supplier_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    }
                }
            },
            "ApiError": {
                "type": "object",
                "required": [
                    "message",
                    "code",
                    "details"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "code": {
                        "type": "string"
                    },
                    "details": {
                        "type": "object"
                    }
                }
            },
            "ValidationApiError": {
                "type": "object",
                "required": [
                    "message",
                    "code",
                    "errors"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "code": {
                        "type": "string",
                        "enum": [
                            "validation_failed"
                        ]
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "AssistantCommand": {
                "type": "object",
                "required": [
                    "action"
                ],
                "properties": {
                    "action": {
                        "type": "string",
                        "description": "Non-destructive command to run.",
                        "enum": [
                            "create_space",
                            "update_space",
                            "create_room",
                            "update_room",
                            "create_zone",
                            "update_zone",
                            "create_supply",
                            "update_supply",
                            "set_supply_status",
                            "move_supply",
                            "create_supplier",
                            "update_supplier",
                            "add_manual_purchase",
                            "update_manual_purchase",
                            "order_manual_purchase",
                            "complete_manual_purchase",
                            "repeat_manual_purchase",
                            "invite_member",
                            "resend_invitation",
                            "update_member_access"
                        ]
                    },
                    "space_id": {
                        "type": "integer",
                        "description": "Space id from context/search."
                    },
                    "room_id": {
                        "type": "integer",
                        "description": "Room id from context/search."
                    },
                    "zone_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Zone id from context/search, or null for no zone."
                    },
                    "supply_id": {
                        "type": "integer",
                        "description": "Supply id from context/search."
                    },
                    "supplier_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Supplier id from context/search."
                    },
                    "manual_entry_id": {
                        "type": "integer",
                        "description": "Manual shopping entry id from context."
                    },
                    "membership_id": {
                        "type": "integer",
                        "description": "Space membership id from context."
                    },
                    "invitation_id": {
                        "type": "integer",
                        "description": "Space invitation id from context."
                    },
                    "name": {
                        "type": "string"
                    },
                    "kind": {
                        "$ref": "#/components/schemas/SpaceKind"
                    },
                    "status": {
                        "description": "Supply status or manual purchase status depending on action.",
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/SupplyStatus"
                            },
                            {
                                "$ref": "#/components/schemas/ManualShoppingStatus"
                            }
                        ]
                    },
                    "access_level": {
                        "$ref": "#/components/schemas/AccessLevel"
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "note": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "address": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "phone": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "categories": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "sort_order": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "stores": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "$ref": "#/components/schemas/SupplyStoreInput"
                        }
                    }
                }
            },
            "AssistantDestructiveCommand": {
                "type": "object",
                "required": [
                    "action",
                    "confirmed"
                ],
                "properties": {
                    "action": {
                        "type": "string",
                        "description": "Destructive command. Ask the user to confirm the exact target first.",
                        "enum": [
                            "delete_space",
                            "delete_room",
                            "delete_zone",
                            "delete_supply",
                            "delete_supplier",
                            "delete_manual_purchase",
                            "cancel_invitation",
                            "remove_member"
                        ]
                    },
                    "confirmed": {
                        "type": "boolean",
                        "description": "Must be true only after explicit user confirmation."
                    },
                    "space_id": {
                        "type": "integer",
                        "description": "Space id from context/search."
                    },
                    "room_id": {
                        "type": "integer",
                        "description": "Room id from context/search."
                    },
                    "zone_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Zone id from context/search, or null for no zone."
                    },
                    "supply_id": {
                        "type": "integer",
                        "description": "Supply id from context/search."
                    },
                    "supplier_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Supplier id from context/search."
                    },
                    "manual_entry_id": {
                        "type": "integer",
                        "description": "Manual shopping entry id from context."
                    },
                    "membership_id": {
                        "type": "integer",
                        "description": "Space membership id from context."
                    },
                    "invitation_id": {
                        "type": "integer",
                        "description": "Space invitation id from context."
                    },
                    "name": {
                        "type": "string"
                    },
                    "kind": {
                        "$ref": "#/components/schemas/SpaceKind"
                    },
                    "status": {
                        "description": "Supply status or manual purchase status depending on action.",
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/SupplyStatus"
                            },
                            {
                                "$ref": "#/components/schemas/ManualShoppingStatus"
                            }
                        ]
                    },
                    "access_level": {
                        "$ref": "#/components/schemas/AccessLevel"
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "note": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "address": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "phone": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "categories": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "sort_order": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "stores": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "$ref": "#/components/schemas/SupplyStoreInput"
                        }
                    }
                }
            }
        }
    }
}