Install
$ agentstack add skill-emgreppi-business-central-ai-skill-consuming-bc-standard-api ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: Consuming BC Standard APIs
Key Concept
Standard APIs are maintained by Microsoft and expose common BC entities. No AL coding required - just authenticate and call the endpoints.
For custom data or business logic, use al-custom-api skill instead.
Validation Gates
- After Step 1: OAuth token acquired successfully
- After Step 2: GET /companies returns company list
- Final: CRUD operations work on target entity
Available Entities (API v2.0)
| Entity | Endpoint | Operations | |--------|----------|------------| | Companies | /companies | GET | | Customers | /customers | GET, POST, PATCH, DELETE | | Vendors | /vendors | GET, POST, PATCH, DELETE | | Items | /items | GET, POST, PATCH, DELETE | | Sales Orders | /salesOrders | GET, POST, PATCH, DELETE | | Sales Invoices | /salesInvoices | GET, POST, PATCH, DELETE | | Purchase Orders | /purchaseOrders | GET, POST, PATCH, DELETE | | Purchase Invoices | /purchaseInvoices | GET, POST, PATCH, DELETE | | General Ledger Entries | /generalLedgerEntries | GET | | Accounts | /accounts | GET | | Dimensions | /dimensions | GET | | Employees | /employees | GET, POST, PATCH, DELETE | | Journal Lines | /journalLines | GET, POST, PATCH, DELETE |
Full list: Microsoft API v2.0 Reference
Procedure
Step 1: Authenticate
Prerequisite: Azure AD App Registration with Dynamics 365 Business Central API permissions.
See al-oauth-integration skill for token acquisition patterns.
Token endpoint:
POST https://login.microsoftonline.com//oauth2/v2.0/token
grant_type=client_credentials
client_id=
client_secret=
scope=https://api.businesscentral.dynamics.com/.default
Step 2: Understand URL Structure
Base URL pattern:
https://api.businesscentral.dynamics.com/v2.0///api/v2.0
With company:
https://api.businesscentral.dynamics.com/v2.0///api/v2.0/companies()/
Placeholder Reference
| Placeholder | Description | Example | |-------------|-------------|---------| | ` | Azure AD tenant ID (GUID) | 12345678-1234-1234-1234-123456789abc | | | BC environment name | Production, Sandbox | | | Company SystemId (GUID) | 87654321-4321-4321-4321-cba987654321 | | | API entity name (camelCase plural) | customers, salesOrders | | | Record SystemId (GUID) | 11111111-2222-3333-4444-555555555555` |
Step 3: Common Operations
GET all companies:
GET /api/v2.0/companies
Authorization: Bearer
GET all customers (with $select):
GET /api/v2.0/companies()/customers?$select=id,number,displayName,email
Authorization: Bearer
GET single customer:
GET /api/v2.0/companies()/customers()
Authorization: Bearer
POST new customer:
POST /api/v2.0/companies()/customers
Authorization: Bearer
Content-Type: application/json
{
"displayName": "New Customer",
"email": "customer@example.com",
"currencyCode": "EUR"
}
PATCH update customer:
PATCH /api/v2.0/companies()/customers()
Authorization: Bearer
Content-Type: application/json
If-Match: *
{
"email": "updated@example.com"
}
DELETE customer:
DELETE /api/v2.0/companies()/customers()
Authorization: Bearer
If-Match: *
Step 4: OData Query Options
$select - Limit returned fields (ALWAYS use for performance):
?$select=id,number,displayName
$filter - Filter results:
?$filter=displayName eq 'Contoso'
?$filter=lastModifiedDateTime gt 2024-01-01T00:00:00Z
?$filter=contains(displayName,'Smith')
$filter with IN operator (BC24+):
Requires $schemaversion=2.1 in URL:
?$schemaversion=2.1&$filter=number in ('10000', '20000', '30000')
Without $schemaversion=2.1, returns error BadRequest_MethodNotImplemented.
$expand - Include related entities:
?$expand=salesOrderLines
?$expand=customer($select=displayName,email)
Filter inside $expand:
?$expand=salesOrderLines($filter=lineType eq 'Item')
Note: Use parentheses () around the nested query options.
Multi-level expand:
?$expand=salesOrderLines($expand=item($expand=itemCategory))
$orderby - Sort results:
?$orderby=displayName
?$orderby=lastModifiedDateTime desc
$count - Get total count:
/salesOrders/$count
Returns integer count of matching records.
Step 5: Handle Pagination
BC uses server-driven paging with @odata.nextLink:
{
"@odata.context": "...",
"value": [...],
"@odata.nextLink": "https://api.../customers?$skiptoken=..."
}
Pattern:
- Make initial request
- Process
valuearray - If
@odata.nextLinkexists, request that URL - Repeat until no more
@odata.nextLink
Do NOT use $top + $skip for paging - poor performance.
Rate Limits
| Environment | Limit | |-------------|-------| | BC Online | 600 requests/minute | | BC On-Premises | Configurable |
HTTP 429 = Too Many Requests → implement exponential backoff.
Troubleshooting
| Error | Cause | Fix | |-------|-------|-----| | 401 | Invalid/expired token | Refresh OAuth token | | 403 | Missing permissions | Check Azure AD API permissions | | 404 | Entity not found | Verify CompanyID and EntityID | | 400 | Invalid request | Check JSON body, field names (camelCase) | | 429 | Rate limited | Implement backoff, reduce request frequency |
Important Notes
- Standard APIs are NOT extensible - you cannot add custom fields
- Use $select always - tables may have extensions adding many fields
- Field names are camelCase -
displayNamenotDisplay Name - SystemId is the key - all entities use GUID as primary key
- If-Match required for PATCH/DELETE - use
*or actual ETag
References
See references/ folder for:
http-examples.md- Complete HTTP request examples for all standard entities (customers, vendors, items, sales orders, etc.)
External Documentation
- Microsoft: API v2.0 Reference
- Microsoft: API Overview
- Microsoft: OData Query Options
- Microsoft: Authentication
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: emgreppi
- Source: emgreppi/Business-Central-AI-Skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.