REST API Add-On
Install the optional B2B Quote REST API add-on when another system needs to work with quotes through Magento Web API. The package declares the routes; the base B2B Quote module provides the service implementations and business rules.
- Package:
mageb2b/b2b-quote-api - Magento module:
MageB2B_B2BQuoteApi
Without this add-on, the REST endpoints documented below are not available. GraphQL is provided by the separate GraphQL Add-On.
Installation
Configure the SoftwareSilo Composer repository if it is not already available, then install the package:
composer config bearer.repo.softwaresilo.io <token>
composer config repositories.softwaresilo composer https://repo.softwaresilo.io/
composer require mageb2b/b2b-quote-api:*
See the installation guide for where to find the repository placeholders and access token (Account > Licenses).
Enable the Magento module and apply the setup changes:
php bin/magento module:enable MageB2B_B2BQuoteApi
php bin/magento setup:upgrade
php bin/magento cache:flush
The add-on has no separate API configuration screen. Create and authorize administrator integrations through Magento's standard integration management.
Authentication
Magento REST authentication depends on the endpoint type:
- Admin / Integration endpoints: Integration token + ACL permission
- Customer endpoints: customer token (
selfresource) - Guest token endpoints:
anonymousaccess but require a guest quote access token
Example (admin/integration token):
curl -X GET "https://your-store.com/rest/V1/b2bquote/quotes" \
-H "Authorization: Bearer {token}"
The examples below show route paths. Request and response bodies follow Magento's generated service-contract schema. Check the target store's Swagger/OpenAPI output or service metadata before implementing a client.
Endpoint Groups
Admin (ACL-protected)
| Method | URL | Purpose |
|---|---|---|
GET |
/V1/b2bquote/quotes |
List quotes (any customer) |
GET |
/V1/b2bquote/quotes/{quoteId} |
Get quote by id |
POST |
/V1/b2bquote/quotes |
Create draft quote |
PUT |
/V1/b2bquote/quotes/{quoteId} |
Save/update quote |
DELETE |
/V1/b2bquote/quotes/{quoteId} |
Delete quote |
POST |
/V1/b2bquote/quotes/{quoteId}/status |
Change status (admin flow) |
POST |
/V1/b2bquote/quotes/{quoteId}/pricing/apply |
Apply pricing rules |
POST |
/V1/b2bquote/quotes/{quoteId}/workflow/apply |
Apply workflow rules |
POST |
/V1/b2bquote/quotes/{quoteId}/approve |
Approve a quote |
POST |
/V1/b2bquote/quotes/{quoteId}/reject |
Reject a quote |
POST |
/V1/b2bquote/quotes/{quoteId}/recalc |
Recalculate quote totals |
POST |
/V1/b2bquote/quotes/{quoteId}/split |
Split a quote into new quotes |
POST |
/V1/b2bquote/quotes/{targetQuoteId}/merge |
Merge source quotes into the target quote |
GET |
/V1/b2bquote/quotes/{quoteId}/history |
Read quote revision history |
Customer (ownership checked)
| Method | URL | Purpose |
|---|---|---|
GET |
/V1/b2bquote/me/quotes |
List my quotes |
GET |
/V1/b2bquote/me/quotes/{quoteId} |
Get my quote |
POST |
/V1/b2bquote/quotes/{quoteId}/submit |
Submit quote |
POST |
/V1/b2bquote/quotes/{quoteId}/accept |
Accept quote |
POST |
/V1/b2bquote/quotes/{quoteId}/items |
Add item |
PUT |
/V1/b2bquote/quotes/{quoteId}/items/{itemId} |
Update item |
DELETE |
/V1/b2bquote/quotes/{quoteId}/items/{itemId} |
Remove item |
POST |
/V1/b2bquote/quotes/{quoteId}/messages |
Add message |
POST |
/V1/b2bquote/quotes/{quoteId}/attachments |
Add attachment |
POST |
/V1/b2bquote/quotes/{quoteId}/addresses |
Set addresses |
POST |
/V1/b2bquote/quotes/{quoteId}/shipping-method |
Set the shipping method |
POST |
/V1/b2bquote/quotes/{quoteId}/payment-method |
Set the payment method |
POST |
/V1/b2bquote/quotes/{quoteId}/items/{itemId}/negotiate |
Submit an item price negotiation |
Guest (token-based)
| Method | URL | Purpose |
|---|---|---|
GET |
/V1/b2bquote/guest/quotes/{token} |
Get guest quote by access token |
POST |
/V1/b2bquote/guest/quotes/{token}/accept |
Accept guest quote by access token |
Categories, Tags, Status Transitions, Revisions (ACL-protected)
| Area | Method | URL |
|---|---|---|
| Categories | GET |
/V1/b2bquote/categories |
| Categories | GET |
/V1/b2bquote/categories/active |
| Categories | GET |
/V1/b2bquote/categories/{categoryId} |
| Categories | POST |
/V1/b2bquote/categories |
| Categories | DELETE |
/V1/b2bquote/categories/{categoryId} |
| Tags | GET |
/V1/b2bquote/tags |
| Tags | GET |
/V1/b2bquote/tags/popular |
| Tags | GET |
/V1/b2bquote/tags/{tagId} |
| Tags | GET |
/V1/b2bquote/quotes/{quoteId}/tags |
| Tags | POST |
/V1/b2bquote/tags |
| Tags | DELETE |
/V1/b2bquote/tags/{tagId} |
| Status transitions | GET |
/V1/b2bquote/statuses/transitions |
| Status transitions | GET |
/V1/b2bquote/statuses/transitions/{id} |
| Status transitions | POST |
/V1/b2bquote/statuses/transitions |
| Status transitions | DELETE |
/V1/b2bquote/statuses/transitions/{id} |
| Revisions | GET |
/V1/b2bquote/quotes/{quoteId}/revisions |
| Revisions | GET |
/V1/b2bquote/revisions/{revisionId} |
| Revisions | GET |
/V1/b2bquote/revisions/{revisionId1}/compare/{revisionId2} |
| Revisions | POST |
/V1/b2bquote/quotes/{quoteId}/revisions |
| Revisions | POST |
/V1/b2bquote/quotes/{quoteId}/revisions/{revisionId}/rollback |
How authorization is applied
- Administrator and integration routes declare a specific
MageB2B_B2BQuote::*ACL resource inwebapi.xml. Grant only the resources the integration needs. - Customer routes use Magento's
selfresource and call ownership-aware service methods. A valid customer token cannot manage another customer's quote. - Guest routes are declared
anonymous, but the quote access token is the authorization secret for that quote. Treat token URLs as sensitive and do not log or expose them unnecessarily. - A valid token does not bypass quote state, access configuration, accept mode, or transition validation.
Customer example
List the authenticated customer's quotes:
curl -X GET "https://your-store.com/rest/V1/b2bquote/me/quotes" \
-H "Authorization: Bearer ${CUSTOMER_TOKEN}" \
-H "Content-Type: application/json"
Keep tokens outside shell history and application logs. The variable name above is illustrative; use your deployment's secret-management approach.
Safe request order
For a customer integration, use the same order as the storefront:
GET /V1/b2bquote/me/quotesand select an owned quote;- add or update items with
product_id,buy_request, andqty, or remove an item by quote and item ID; - set
billingandshippingaddress objects; - set the shipping method code and, when required, the payment method code;
- send messages, attachments, or a customer counter price;
- submit the quote, then accept it with the required accept mode.
The service contract recalculates totals after item and commercial changes.
Read the quote again after each mutation and use the returned updated_at and
status before sending the next write. An ownership check is performed by the
customer methods, so an ID from another customer must not be treated as an
empty result.
Canonical request shapes
The exact JSON wrapper is generated by Magento Web API. The following fields are the service-contract payload, not a promise that every custom extension will accept additional fields:
{
"quoteId": 42,
"productId": 1001,
"buyRequest": {
"sku": "office-chair",
"name": "Office chair",
"price": 199.00,
"super_attribute": {"color": "black"}
},
"qty": 10
}
For item updates, use qty, offered_price, customer_counter_price, and
notes. For addresses use the quote address fields such as firstname,
lastname, street, city, region, postcode, country_id, and
telephone. The shipping and payment calls receive their method code.
Inspect the generated Swagger schema for the surrounding interface parameter
names before serializing the request.
The accept call accepts create_order or add_to_cart according to the base
service contract and store configuration. Its integer response identifies the
created order in create_order mode or the active cart in add_to_cart mode.
Idempotency and retries
The add-on does not add a separate idempotency key. A timeout after a mutation is ambiguous. Read the quote and order/cart state before retrying acceptance, and use a client-side request ID in your integration logs. A retry of an item add or message post can create a duplicate even if the first response was not received.
Errors and diagnostics
| Code | Description |
|---|---|
400 |
The payload or business input is invalid |
401 |
The bearer token is missing, expired, or not accepted for the route |
403 |
The integration lacks the declared ACL resource or the actor cannot perform the operation |
404 |
The quote or related entity is not available to that context |
Magento serializes service exceptions according to its Web API behavior. Do not build client logic around an undocumented assumption that every invalid transition returns one specific status code; inspect the error body and verify the target Magento API schema.
This add-on does not add a separate B2B Quote rate limiter, rate-limit response headers, configurable quote webhooks, or a B2B Quote > API configuration group. Infrastructure-level limits from a CDN, WAF, reverse proxy, or another Magento module can still apply.
When a call fails:
- Confirm the route exists in the target store's generated API schema.
- Confirm the token type matches the route: administrator/integration, customer, or guest access token.
- Check the exact ACL resource for integration routes.
- Check ownership and the quote's current state/status.
- Reproduce with a read operation before retrying a mutation.
- Review Magento's
var/log/system.logandvar/log/exception.logfor the corresponding request time.