swagger: '2.0' info: title: Foodsoft API v1 version: '1.0.0' description: > [Foodsoft](https://github.com/foodcoops/foodsoft) is web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling). This is a description of Foodsoft's API v1. Note that each food cooperative typically has their own instance (on a shared server or their own installation), and there are just as many APIs (if the Foodsoft version is recent enough). This API description points to the default development url with the default Foodsoft scope - that would be [http://localhost:3000/f](http://localhost:3000/f). You may find the search parameters for index endpoints lacking. They are not documented here, because there are too many combinations. For now, you'll need to resort to [Ransack](https://github.com/activerecord-hackery/ransack) and looking at Foodsoft's `ransackable_*` model class methods. externalDocs: description: General Foodsoft API documentation url: https://github.com/foodcoops/foodsoft/blob/master/doc/API.md # development url with default scope host: localhost:3000 schemes: - 'http' basePath: /f/api/v1 produces: - 'application/json' paths: /user: get: summary: info about the currently logged-in user tags: - 1. User responses: 200: description: success schema: type: object properties: user: $ref: '#/definitions/User' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['user:read', 'user:write'] /user/financial_overview: get: summary: financial summary about the currently logged-in user tags: - 1. User - 6. FinancialTransaction responses: 200: description: success schema: type: object properties: financial_overview: $ref: '#/definitions/FinanceOverview' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['finance:user'] /user/financial_transactions: get: summary: financial transactions of the member's ordergroup tags: - 1. User - 6. FinancialTransaction parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: financial_transactions: type: array items: $ref: '#/definitions/FinancialTransaction' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup or missing scope schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['finance:user'] post: summary: create new financial transaction (requires enabled self service) tags: - 1. User - 6. FinancialTransaction parameters: - in: body name: body description: financial transaction to create required: true schema: $ref: '#/definitions/FinancialTransactionForCreate' responses: 200: description: success schema: type: object properties: financial_transaction: $ref: '#/definitions/FinancialTransaction' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup, is below minimum balance, self service is disabled, or missing scope schema: $ref: '#/definitions/Error403' 404: description: financial transaction type not found schema: $ref: '#/definitions/Error404' 422: description: invalid parameter value schema: $ref: '#/definitions/Error422' /user/financial_transactions/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find financial transaction by id tags: - 1. User - 6. FinancialTransaction responses: 200: description: success schema: type: object properties: financial_transaction: $ref: '#/definitions/FinancialTransaction' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup or missing scope schema: $ref: '#/definitions/Error403' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['finance:user'] /user/group_order_articles: get: summary: group order articles tags: - 1. User - 2. Order parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' - $ref: '#/parameters/q_ordered' responses: 200: description: success schema: type: object properties: group_order_articles: type: array items: $ref: '#/definitions/GroupOrderArticle' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup or missing scope schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['group_orders:user'] post: summary: create new group order article tags: - 1. User - 2. Order parameters: - in: body name: body description: group order article to create required: true schema: $ref: '#/definitions/GroupOrderArticleForCreate' responses: 200: description: success schema: type: object properties: group_order_article: $ref: '#/definitions/GroupOrderArticle' order_article: $ref: '#/definitions/OrderArticle' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope schema: $ref: '#/definitions/Error403' 404: description: order article not found in open orders schema: $ref: '#/definitions/Error404' 422: description: invalid parameter value or group order article already exists schema: $ref: '#/definitions/Error422' /user/group_order_articles/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find group order article by id tags: - 1. User - 2. Order responses: 200: description: success schema: type: object properties: group_order_article: $ref: '#/definitions/GroupOrderArticle' order_article: $ref: '#/definitions/OrderArticle' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup or missing scope schema: $ref: '#/definitions/Error403' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['group_orders:user'] patch: summary: update a group order article (but delete if quantity and tolerance are zero) tags: - 1. User - 2. Order parameters: - $ref: '#/parameters/idInUrl' - in: body name: body description: group order article update required: true schema: $ref: '#/definitions/GroupOrderArticleForUpdate' responses: 200: description: success schema: type: object properties: group_order_article: $ref: '#/definitions/GroupOrderArticle' order_article: $ref: '#/definitions/OrderArticle' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope schema: $ref: '#/definitions/Error403' 404: description: order article not found in open orders schema: $ref: '#/definitions/Error404' 422: description: invalid parameter value schema: $ref: '#/definitions/Error422' delete: summary: remove group order article tags: - 1. User - 2. Order parameters: - $ref: '#/parameters/idInUrl' responses: 200: description: success schema: type: object properties: group_order_article: $ref: '#/definitions/GroupOrderArticle' order_article: $ref: '#/definitions/OrderArticle' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope schema: $ref: '#/definitions/Error403' 404: description: order article not found in open orders schema: $ref: '#/definitions/Error404' /financial_transactions: get: summary: financial transactions tags: - 6. FinancialTransaction parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: financial_transactions: type: array items: $ref: '#/definitions/FinancialTransaction' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['finance:read', 'finance:write'] /financial_transactions/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find financial transaction by id tags: - 6. FinancialTransaction responses: 200: description: success schema: type: object properties: financial_transaction: $ref: '#/definitions/FinancialTransaction' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['finance:read', 'finance:write'] /orders: get: summary: orders tags: - 2. Order parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: orders: type: array items: $ref: '#/definitions/Order' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['orders:read', 'orders:write'] /orders/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find order by id tags: - 2. Order responses: 200: description: success schema: type: object properties: order: $ref: '#/definitions/Order' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['orders:read', 'orders:write'] /order_articles: get: summary: order articles tags: - 2. Order parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' - $ref: '#/parameters/q_ordered' responses: 200: description: success schema: type: object properties: order_articles: type: array items: $ref: '#/definitions/OrderArticle' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['group_orders:user'] /order_articles/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find order article by id tags: - 2. Order responses: 200: description: success schema: type: object properties: order_article: $ref: '#/definitions/OrderArticle' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['orders:read', 'orders:write'] /article_categories: get: summary: article categories tags: - 2. Category parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: article_categories: type: array items: $ref: '#/definitions/ArticleCategory' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' security: - foodsoft_auth: ['all'] /article_categories/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find article category by id tags: - 2. Category responses: 200: description: success schema: type: object properties: article_category: $ref: '#/definitions/ArticleCategory' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['all'] /financial_transaction_classes: get: summary: financial transaction classes tags: - 2. Category parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: financial_transaction_classes: type: array items: $ref: '#/definitions/FinancialTransactionClass' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' security: - foodsoft_auth: ['all'] /financial_transaction_classes/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find financial transaction class by id tags: - 2. Category responses: 200: description: success schema: type: object properties: financial_transaction_class: $ref: '#/definitions/FinancialTransactionClass' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['all'] /financial_transaction_types: get: summary: financial transaction types tags: - 2. Category parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: description: success schema: type: object properties: financial_transaction_types: type: array items: $ref: '#/definitions/FinancialTransactionType' meta: $ref: '#/definitions/Meta' 401: description: not logged-in schema: $ref: '#/definitions/Error401' security: - foodsoft_auth: ['all'] /financial_transaction_types/{id}: parameters: - $ref: '#/parameters/idInUrl' get: summary: find financial transaction type by id tags: - 2. Category responses: 200: description: success schema: type: object properties: financial_transaction_type: $ref: '#/definitions/FinancialTransactionType' 401: description: not logged-in schema: $ref: '#/definitions/Error401' 404: description: not found schema: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['all'] /config: get: summary: configuration variables tags: - 7. General responses: 200: description: success schema: type: object 401: description: not logged-in schema: $ref: '#/definitions/Error401' 403: description: missing scope or no permission schema: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['config:user', 'config:read', 'config:write'] /navigation: get: summary: navigation tags: - 7. General responses: 200: description: success schema: type: object properties: navigation: $ref: '#/definitions/Navigation' 401: description: not logged-in schema: $ref: '#/definitions/Error401' security: - foodsoft_auth: [] parameters: # url parameters idInUrl: name: id type: integer in: path minimum: 1 required: true # query parameters page: name: page type: integer in: query description: page number minimum: 0 default: 0 per_page: name: per_page type: integer in: query description: items per page minimum: 0 default: 20 # non-ransack query parameters q_ordered: name: q[ordered] type: string in: query description: "'member' show articles ordered by the user's ordergroup, 'all' by all members, and 'supplier' ordered at the supplier" enum: ['member', 'all', 'supplier'] definitions: # models User: type: object properties: id: type: integer name: type: string description: full name email: type: string description: email address locale: type: string description: language code required: ['id', 'name', 'email'] FinancialTransactionForCreate: type: object properties: amount: type: number description: amount credited (negative for a debit transaction) financial_transaction_type_id: type: integer description: id of the type of the transaction note: type: string description: note entered with the transaction required: ['amount', 'financial_transaction_type_id', 'note'] FinancialTransaction: allOf: - $ref: '#/definitions/FinancialTransactionForCreate' - type: object properties: id: type: integer user_id: type: ['integer', 'null'] description: id of user who entered the transaction (may be null for deleted users or 0 for a system user) user_name: type: ['string', 'null'] description: name of user who entered the transaction (may be null or empty string for deleted users or system users) financial_transaction_type_name: type: string description: name of the type of the transaction created_at: type: string format: date-time description: when the transaction was entered required: ['id', 'user_id', 'user_name', 'financial_transaction_type_name', 'created_at'] FinancialTransactionClass: type: object properties: id: type: integer name: type: string description: full name required: ['id', 'name'] FinancialTransactionType: type: object properties: id: type: integer name: type: string description: full name name_short: type: ['string', 'null'] description: short name (used for bank transfers) bank_account_id: type: ['integer', 'null'] description: id of the bank account used for this transaction type bank_account_name: type: ['string', 'null'] description: name of the bank account used for this transaction type bank_account_iban: type: ['string', 'null'] description: IBAN of the bank account used for this transaction type financial_transaction_class_id: type: integer description: id of the class of the transaction financial_transaction_class_name: type: string description: name of the class of the transaction required: ['id', 'name', 'financial_transaction_class_id', 'financial_transaction_class_name'] FinanceOverview: type: object properties: account_balance: type: number description: booked accout balance of ordergroup available_funds: type: number description: fund available to order articles financial_transaction_class_sums: type: array items: type: object properties: id: type: integer description: id of the financial transaction class name: type: string description: name of the financial transaction class amount: type: number description: sum of the amounts belonging to the financial transaction class required: ['id', 'name', 'amount'] required: ['account_balance', 'available_funds', 'financial_transaction_class_sums'] ArticleCategory: type: object properties: id: type: integer name: type: string required: ['id', 'name'] Order: type: object properties: id: type: integer name: type: string description: name of the order's supplier (or stock) starts: type: string format: date-time description: when the order was opened ends: type: ['string', 'null'] format: date-time description: when the order will close or was closed boxfill: type: ['string', 'null'] format: date-time description: when the order will enter or entered the boxfill phase pickup: type: ['string', 'null'] format: date description: pickup date is_open: type: boolean description: if the order is currently open or not is_boxfill: type: boolean description: if the order is currently in the boxfill phase or not Article: type: object properties: id: type: integer name: type: string supplier_id: type: integer description: id of supplier, or 0 for stock articles supplier_name: type: ['string', 'null'] description: name of the supplier, or null for stock articles unit: type: string description: amount of each unit, e.g. "100 g" or "kg" unit_quantity: type: integer description: units can only be ordered from the supplier in multiples of unit_quantity note: type: ['string', 'null'] description: generic note manufacturer: type: ['string', 'null'] description: manufacturer origin: type: ['string', 'null'] description: origin, preferably (starting with a) 2-letter ISO country code article_category_id: type: integer description: id of article category quantity_available: type: integer description: number of units available (only present on stock articles) required: ['id', 'name', 'supplier_id', 'supplier_name', 'unit', 'unit_quantity', 'note', 'manufacturer', 'origin', 'article_category_id'] OrderArticle: type: object properties: id: type: integer order_id: type: integer description: id of order this order article belongs to price: type: number format: float description: foodcoop price quantity: type: integer description: number of units ordered by members tolerance: type: integer description: number of extra units that members are willing to buy to fill a box units_to_order: type: integer description: number of units to order from the supplier article: $ref: '#/definitions/Article' GroupOrderArticleForUpdate: type: object properties: quantity: type: integer description: number of units ordered by the user's ordergroup tolerance: type: integer description: number of extra units the user's ordergroup is willing to buy for filling a box GroupOrderArticleForCreate: allOf: - $ref: '#/definitions/GroupOrderArticleForUpdate' - type: object properties: order_article_id: type: integer description: id of order article GroupOrderArticle: allOf: - $ref: '#/definitions/GroupOrderArticleForCreate' - type: object properties: id: type: integer result: type: number format: float description: number of units the user's ordergroup will receive or has received total_price: type: number format: float description: total price of this group order article Navigation: type: array items: type: object properties: name: type: string description: title url: type: string description: link items: $ref: '#/definitions/Navigation' required: ['name'] minProperties: 2 # name+url or name+items # collection meta object in root of a response Meta: type: object properties: page: type: integer description: page number of the returned collection per_page: type: integer description: number of items per page total_pages: type: integer description: total number of pages total_count: type: integer description: total number of items in the collection required: ['page', 'per_page', 'total_pages', 'total_count'] Error: type: object properties: error: type: string description: error code error_description: type: string description: human-readable error message (localized) Error404: type: object properties: error: type: string description: 'not_found' error_description: $ref: '#/definitions/Error/properties/error_description' Error401: type: object properties: error: type: string description: 'unauthorized' error_description: $ref: '#/definitions/Error/properties/error_description' Error403: type: object properties: error: type: string description: 'forbidden or invalid_scope' error_description: $ref: '#/definitions/Error/properties/error_description' Error422: type: object properties: error: type: string description: unprocessable entity error_description: $ref: '#/definitions/Error/properties/error_description' securityDefinitions: foodsoft_auth: type: oauth2 flow: implicit authorizationUrl: http://localhost:3000/f/oauth/authorize scopes: config:user: reading Foodsoft configuration for regular users config:read: reading Foodsoft configuration values config:write: reading and updating Foodsoft configuration values finance:user: accessing your own financial transactions finance:read: reading all financial transactions finance:write: reading and creating financial transactions user:read: reading your own user profile user:write: reading and updating your own user profile offline_access: retain access after user has logged out