APIBuilder Documentation
Overview
The APIBuilder provides a fluent interface for making authenticated API calls to MAGICapp's API. It's automatically available through the magicapp-connect component and includes predefined methods for common endpoints plus a flexible builder pattern for custom API calls.
Installation
The APIBuilder will lazy load via the magicapp-connect component.
<script type="module">
import 'https://app.magicapp.org/widget/connectServiceComponent.js';
</script>
Basic Usage
Access the APIBuilder through a connected magicapp-connect component:
const connector = document.querySelector('magicapp-connect');
// Wait for connection
connector.addEventListener('connected', async () => {
// Now you can use the API
const guidelines = await connector.api.guidelines.getAll();
console.log(guidelines);
});
Predefined APIs
The APIBuilder includes predefined methods for common MAGICapp endpoints.
Guidelines API
Access guideline data through convenient methods:
const connector = document.querySelector('magicapp-connect');
// Get all guidelines
const guidelines = await connector.api.guidelines.getAll(queryParams);
// Get guideline by ID
const guideline = await connector.api.guidelines.getById(id);
// Get current published guideline by short code
const current = await connector.api.guidelines.getCurrentPublishedGuideline(shortCode);
// Get latest guideline IDs
const ids = await connector.api.guidelines.getLatestGuidelineIds(shortCode);
// Get recommendation metadata for a guideline
const meta = await connector.api.guidelines.getMetaByGuideline(guidelineId);
Guidelines API Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
getAll(queryParams?) | queryParams (object, optional) | Promise<Array> | Get all guidelines with optional query filters |
getById(id) | id (long) | Promise<Object> | Get specific guideline by ID |
getCurrentPublishedGuideline(shortCode) | shortCode (string) | Promise<Object> | Get the current published version by short code |
getLatestGuidelineIds(shortCode) | shortCode (string) | Promise<Object> | Get the latest guideline version IDs |
getMetaByGuideline(guidelineId) | guidelineId (long) | Promise<Array> | Get recommendation metadata for a guideline |
getGuidelineToc(guidelineId) | guidelineId (long) | Promise<Array> | Get Table of Contents |
getSection(guidelineId, sectionId) | guidelineId (long), sectonId (long) | Promise<Array> | Get a single Section |
getSections(guidelineId) | guidelineId (long) | Promise<Array> | Get all sections for a Guideline |
getSectionText(guidelineId) | guidelineId (long), sectonId (long) | Promise<Array> | Get just the text for a single Section |
Guidelines API Examples
// Get all guidelines
const allGuidelines = await connector.api.guidelines.getAll();
// Get guidelines with query parameters
const filteredGuidelines = await connector.api.guidelines.getAll({
status: 'published',
limit: 10
});
// Get specific guideline
const guideline = await connector.api.guidelines.getById('123456');
// Get current published version
const current = await connector.api.guidelines.getCurrentPublishedGuideline('x1j32ks'); // shortcode
// Get latest IDs for a guideline
const ids = await connector.api.guidelines.getLatestGuidelineIds('x1j32ks'); // shortcode
console.log(ids);
// {
// currentPublished: { guidelineId: '12345', version: '2.1' },
// latest: { guidelineId: '12346', version: '2.2' }
// }
// Get all recommendations for a guideline
const recommendations = await connector.api.guidelines.getMetaByGuideline('12345');
recommendations.forEach(rec => {
console.log(rec.recommendationId, rec.title);
});
Fluent Builder Pattern
For custom API endpoints not covered by predefined methods, use the fluent builder:
Basic Builder Usage
const connector = document.querySelector('magicapp-connect');
// GET request
const data = await connector.api
.get()
.endpoint('/api/v1/resource')
.execute();
// POST request
const created = await connector.api
.post()
.endpoint('/api/v1/resource')
.body({ name: 'Example', value: 42 })
.execute();
// PUT request
const updated = await connector.api
.put()
.endpoint('/api/v1/resource/{id}')
.pathParams({ id: 123 })
.body({ name: 'Updated' })
.execute();
Builder Methods
HTTP Methods
Set the HTTP method for your request:
// GET request
connector.api.get()
// POST request
connector.api.post()
// PUT request
connector.api.put()
Set the API endpoint path. Supports path parameter placeholders using {param} syntax:
// Simple endpoint
.endpoint('/api/v1/guidelines')
// Endpoint with path parameters
.endpoint('/api/v1/guidelines/{id}')
.endpoint('/api/v1/users/{userId}/posts/{postId}')
Parameters:
path(string): API endpoint path with optional{param}placeholders
Returns: Builder instance (chainable)
path Params(params)
Replace path parameter placeholders with actual values:
.endpoint('/api/v1/users/{userId}/posts/{postId}')
.pathParams({ userId: 123, postId: 456 })
// Results in: /api/v1/users/123/posts/456
Parameters:
params(object): Key-value pairs where keys match placeholder names
Returns: Builder instance (chainable)
Note: Values are automatically URL-encoded.
query(params)
Add query string parameters:
.endpoint('/api/v1/guidelines')
.query({ page: 1, size: 20, sort: 'name' })
// Results in: /api/v1/guidelines?page=1&size=20&sort=name
Parameters:
params(object): Key-value pairs for query parameters
Returns: Builder instance (chainable)
Note: Multiple calls to query() will merge parameters.
body(data)
Set the request body (for POST, PUT, PATCH requests):
.post()
.endpoint('/api/v1/resource')
.body({ name: 'Example', value: 42 })
Parameters:
data(object): Data to send (will be JSON.stringify'd automatically)
Returns: Builder instance (chainable)
Note: Body is automatically ignored for GET and DELETE requests.
headers(headers)
Add custom headers to the request:
.endpoint('/api/v1/resource')
.headers({
'X-Custom-Header': 'value',
'X-Request-ID': '12345'
})
Parameters:
headers(object): Key-value pairs for custom headers
Returns: Builder instance (chainable)
Note: The Authorization and Content-Type headers are set automatically.
execute() / send()
Execute the built request:
const result = await connector.api
.get()
.endpoint('/api/v1/resource')
.execute();
// Or use send() - it's an alias
const result = await connector.api
.get()
.endpoint('/api/v1/resource')
.send();
Returns: Promise<any> - Parsed JSON response
Throws: Error if the request fails or the token is invalid
Complete Examples
Example 1: Get Guidelines with Filtering
const connector = document.querySelector('magicapp-connect');
connector.addEventListener('connected', async () => {
try {
// Using predefined method
const guidelines = await connector.api.guidelines.getAll({
name: 'cardiology',
limit: 10
});
displayGuidelines(guidelines);
} catch (error) {
console.error('Failed to load guidelines:', error);
}
});
Example 2: Complex Workflow
const connector = document.querySelector('magicapp-connect');
connector.addEventListener('connected', async () => {
try {
// Step 1: Get all guidelines
const guidelines = await connector.api.guidelines.getAll();
console.log('Found', guidelines.length, 'guidelines');
// Step 2: Get latest IDs for first guideline
const ids = await connector.api.guidelines.getLatestGuidelineIds(
guidelines[0].shortCode
);
console.log('Latest guideline ID:', ids.currentPublished.guidelineId);
// Step 3: Get recommendations for this guideline
const recommendations = await connector.api.guidelines.getMetaByGuideline(
ids.currentPublished.guidelineId
);
console.log('Found', recommendations.length, 'recommendations');
// Step 4: Display first 5 recommendations
recommendations.slice(0, 5).forEach(rec => {
console.log(`- ${rec.title} (ID: ${rec.recommendationId})`);
});
} catch (error) {
console.error('Workflow failed:', error);
}
});
Example 3: Custom Endpoint with Builder
const connector = document.querySelector('magicapp-connect');
connector.addEventListener('connected', async () => {
try {
// Custom GET with path params and query
const user = await connector.api
.get()
.endpoint('/api/v1/users/{userId}')
.pathParams({ userId: 123 })
.query({ include: 'profile,permissions' })
.execute();
console.log('User:', user);
// Custom POST
const newResource = await connector.api
.post()
.endpoint('/api/v1/resources')
.body({
title: 'New Resource',
content: 'Resource content here',
tags: ['tag1', 'tag2']
})
.execute();
console.log('Created:', newResource);
// Custom PUT with headers
const updated = await connector.api
.put()
.endpoint('/api/v1/resources/{id}')
.pathParams({ id: newResource.id })
.headers({ 'X-Update-Reason': 'User requested change' })
.body({ title: 'Updated Title' })
.execute();
console.log('Updated:', updated);
} catch (error) {
console.error('API call failed:', error);
}
});
Example 4: Pagination
async function loadAllGuidelines() {
const connector = document.querySelector('magicapp-connect');
let allGuidelines = [];
let page = 1;
const pageSize = 20;
while (true) {
const result = await connector.api
.get()
.endpoint('/api/v1/guidelines')
.query({ offset: page, limit: pageSize })
.execute();
allGuidelines = allGuidelines.concat(result.items);
if (result.items.length < pageSize) {
break; // Last page
}
page++;
}
return allGuidelines;
}
Example 5: Error Handling
const connector = document.querySelector('magicapp-connect');
connector.addEventListener('connected', async () => {
try {
const data = await connector.api.guidelines.getAll();
displayData(data);
} catch (error) {
// Handle different error types
if (error.message.includes('Not connected')) {
alert('Please connect to MAGICapp first');
} else if (error.message.includes('reconnect')) {
alert('Your session expired. Please reconnect.');
connector.disconnect();
} else if (error.message.includes('401')) {
alert('Authentication failed. Please reconnect.');
connector.disconnect();
} else if (error.message.includes('403')) {
alert('You do not have permission to access this resource');
} else if (error.message.includes('404')) {
alert('Resource not found');
} else {
console.error('API Error:', error);
alert('An error occurred. Please try again.');
}
}
});
API Endpoints Reference
Base URLs
- Production: https://api.magicapp.org
- Test: https://api-test.magicapp.org
- Local: http://localhost:8080
The base URL is automatically selected based on your environment.
Common Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/v1/guidelines | GET | Get all guidelines |
/api/v1/guidelines/{id} | GET | Get a guideline by ID |
/api/v1/guidelines/{shortCode}/current | GET | Get the current published guideline |
/api/v2/guidelines/{shortCode}/latest | GET | Get latest guideline IDs |
/api/v2/guidelines/{gId}/recommendation/meta | GET | Get recommendation metadata |
Note: The predefined guidelines API methods handle these endpoints for you.
Authentication
All API requests made through the APIBuilder are automatically authenticated:
- Access Token: Automatically included
Authorization: Bearer {token}in the header - Auto-Refresh: If a token is expired or expiring soon (< 60s), it's automatically refreshed
- Public Fallback: If no token is available, the request is made as a public user (no auth header)
You don't need to manually manage authentication—the magicapp-connect component handles it.
Error Handling
Common Error Scenarios
try {
const data = await connector.api.guidelines.getAll();
} catch (error) {
// Error types you might encounter:
// 1. Not connected
if (error.message.includes('Not connected')) {
// User needs to connect first
}
// 2. Token expired
if (error.message.includes('reconnect')) {
// Session expired, prompt reconnection
}
// 3. Network error
if (error.message.includes('Failed to fetch')) {
// Network issue or API is down
}
// 4. HTTP errors
if (error.message.includes('401')) {
// Unauthorized - auth failed
}
if (error.message.includes('403')) {
// Forbidden - no permission
}
if (error.message.includes('404')) {
// Not found
}
if (error.message.includes('500')) {
// Server error
}
}
Best Practices
- Always use try-catch when making API calls
- Listen for
errorevents on the connector - Check connection status before making calls
- Provide user feedback for all error scenarios
- Log errors for debugging (but not tokens!)
Rate Limits
MAGICapp API enforces rate limits:
- API endpoints: 1000 requests per hour per user
- Token endpoint: 10 requests per minute per client
Exceeding limits returns 429 Too Many Requests with a Retry-After header.
Handling Rate Limits
try {
const data = await connector.api.guidelines.getAll();
} catch (error) {
if (error.message.includes('429')) {
alert('Rate limit exceeded. Please wait and try again.');
// Optionally parse Retry-After header
}
}
Testing
Test Environment
Use the test environment for development:
<!-- Your app at app-test.magicapp.org automatically uses test environment -->
<magicapp-connect client-id="your-client-id" env="test"></magicapp-connect>
Test environment automatically provides:
- Test API: https://api-test.magicapp.org
- Test Auth: https://auth-test.magicapp.org
- Separate test data from production
Local Development
For local development:
<!-- Your app at localhost automatically uses local environment -->
<magicapp-connect client-id="your-client-id" env="local"></magicapp-connect>
Requires running local services:
- Local API: http://localhost:8080
- Local Auth: http://localhost:8180
TypeScript Support
While the component is written in vanilla JavaScript, you can add type definitions for better IDE support:
interface Guideline {
id: string;
name: string;
shortCode: string;
version: string;
status: string;
}
interface GuidelineIds {
currentPublished: {
guidelineId: string;
version: string;
};
latest: {
guidelineId: string;
version: string;
};
}
interface RecommendationMeta {
recommendationId: string;
title: string;
text: string;
strength: string;
}
// Use with API calls
const guidelines: Guideline[] = await connector.api.guidelines.getAll();
const ids: GuidelineIds = await connector.api.guidelines.getLatestGuidelineIds(shortCode);
const meta: RecommendationMeta[] = await connector.api.guidelines.getMetaByGuideline(guidelineId);
Browser Compatibility
The APIBuilder works in all modern browsers that support:
- ES6 Modules
- Promises/async-await
- Fetch API
- URLSearchParams
Supported browsers:
- Chrome/Edge 80+
- Firefox 75+
- Safari 13.1+
- Opera 67+
Support
- Email: api-support@magicapp.org
- Documentation: https://docs.magicapp.org
- Examples: https://magicevidence.org/widget-auth-demo
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article