Approvals
Integrate Marq Approvals with other applications using REST APIs and webhooks for real-time, bi-directional updates.
Overview
Marq's Approval system enables organizations to implement structured content review workflows, ensuring quality control and brand compliance before content goes live. This guide covers both the conceptual framework and technical implementation for developers building approval workflows.
Key Benefits:
- Quality Control: Enforce brand, legal, and regulatory standards
- Audit Trail: Maintain detailed approval history with timestamps and comments
- Workflow Automation: Streamline review processes with automated notifications
- Compliance: Meet organizational governance requirements
Understanding the Approval Architecture
Core Components
The Marq approval system consists of four primary components:
- Approval Requests: Initiated when content needs review
- Approval Targets: The content being reviewed (projects, templates)
- Approvers: Users with permission to approve or decline requests
- Approval States: Current status of the approval process
Approval Flow
Project Created → Approval Request → Pending Review → Approved/Declined → Final State
Approval States
State | Description | Next Actions |
---|---|---|
pending_approval | Awaiting reviewer action | Approve or decline |
approved | Content has been approved | Content can be published/used |
declined | Content has been rejected | Requires revision |
Getting Started
Prerequisites
- Valid Marq API credentials (OAuth2 or API key)
- Appropriate permissions for approval management
- Understanding of your organization's approval workflow
Authentication
All approval endpoints require authentication. Use OAuth2 for user-specific actions:
# OAuth2 Token Request
curl -X POST "https://users.app.marq.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=YOUR_CODE&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
Core Approval APIs
1. Get Approvals
Retrieve approval requests with optional filtering.
Endpoint: GET /v1/approvals
Parameters:
requesterId
(optional): Filter by user who requested approvalapproverId
(optional): Filter by assigned approverapprovalTarget
(optional): Filter by specific content IDapprovalState
(optional): Filter by approval state
Example Request:
curl -X GET "https://api.marq.com/v1/approvals?approvalState=pending_approval" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example Response:
{
"approvals": [
{
"id": "approval-123",
"approvalTarget": "project-456",
"requesterId": 164359417,
"approverId": 164359412,
"approvalState": "pending_approval",
"comments": "Please review for brand compliance",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 25,
"total": 1
}
}
2. Create Approval Request
Submit content for approval review.
Endpoint: POST /v1/projects/{project_id}/approvals
Required Parameters:
sendToId
: User ID of the approverapprovalState
: Should be "pending_approval"comments
: Review instructions or context
Example Request:
curl -X POST "https://api.marq.com/v1/projects/project-456/approvals" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"approvalState": "pending_approval",
"comments": "Please review this marketing flyer for Q1 campaign compliance",
"sendToId": 164359412
}'
Example Response:
{
"id": "approval-789",
"approvalTarget": "project-456",
"requesterId": 164359417,
"approverId": 164359412,
"approvalState": "pending_approval",
"comments": "Please review this marketing flyer for Q1 campaign compliance",
"createdAt": "2024-01-15T11:00:00Z"
}
3. Update Approval Status
Approve or decline a pending approval request.
Endpoint: PUT /v1/approvals/{targetId}
Required Parameters:
approvalStatus
: "approved" or "declined"
Example Request (Approve):
curl -X PUT "https://api.marq.com/v1/approvals/project-456" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"approvalStatus": "approved"
}'
Example Request (Decline):
curl -X PUT "https://api.marq.com/v1/approvals/project-456" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"approvalStatus": "declined",
"comments": "Brand colors need to be updated per latest guidelines"
}'
async function bulkApprovalUpdate(approvals, status) {
const updates = approvals.map(approval =>
fetch(`https://api.marq.com/v1/approvals/${approval.targetId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
approvalStatus: status
})
})
);
const results = await Promise.allSettled(updates);
return results.map((result, index) => ({
targetId: approvals[index].targetId,
success: result.status === 'fulfilled',
error: result.status === 'rejected' ? result.reason : null
}));
}
Webhook Integration
Setting Up Approval Webhooks
Configure webhooks to receive real-time approval notifications:
curl -X POST "https://api.marq.com/v1/webhook" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/marq-approvals",
"name": "Approval Notifications",
"eventTypes": [
"approval.created",
"approval.approved",
"approval.declined"
]
}'
Webhook Event Handling
Process incoming webhook events:
app.post('/webhooks/marq-approvals', (req, res) => {
const event = req.body;
switch (event.eventType) {
case 'approval.created':
handleApprovalCreated(event.data);
break;
case 'approval.approved':
handleApprovalApproved(event.data);
break;
case 'approval.declined':
handleApprovalDeclined(event.data);
break;
}
res.status(200).send('OK');
});
function handleApprovalCreated(data) {
// Send notification to approver
// Update internal tracking system
console.log(`New approval request: ${data.approvalTarget}`);
}
function handleApprovalApproved(data) {
// Trigger publication workflow
// Update project status
console.log(`Content approved: ${data.approvalTarget}`);
}
function handleApprovalDeclined(data) {
// Notify content creator
// Log feedback for revision
console.log(`Content declined: ${data.approvalTarget}`, data.comments);
}
Best Practices
1. Error Handling
Implement comprehensive error handling:
async function safeApprovalRequest(projectId, approverId, comments) {
try {
const response = await fetch(`https://api.marq.com/v1/projects/${projectId}/approvals`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
approvalState: 'pending_approval',
sendToId: approverId,
comments: comments
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Approval request failed: ${errorData.message}`);
}
return await response.json();
} catch (error) {
console.error('Approval request error:', error);
// Implement retry logic for network errors
if (error.message.includes('network')) {
return retryApprovalRequest(projectId, approverId, comments);
}
throw error;
}
}
2. Security Considerations
- Validate permissions: Ensure users can only approve content they're authorized to review
- Audit logging: Track all approval actions for compliance
- Rate limiting: Implement request throttling to prevent abuse
function validateApprovalPermissions(userId, targetId) {
// Check if user has approval permissions for this content
// Verify user is assigned as approver
// Validate content exists and is in correct state
}
Error Handling Reference
Common Error Codes
Error Code | Description | Resolution |
---|---|---|
401 | Unauthorized | Verify access token is valid |
403 | Forbidden | Check user permissions |
404 | Not Found | Verify project/approval ID exists |
422 | Validation Error | Check required parameters |
429 | Rate Limited | Implement retry with backoff |
Error Response Format
{
"error": {
"code": "APPROVAL_NOT_FOUND",
"message": "The specified approval request does not exist",
"details": {
"approvalId": "invalid-id",
"timestamp": "2024-01-15T12:00:00Z"
}
}
}
Related Documentation
Notes
- Approval requests are tied to specific projects and cannot be transferred
- Approvers must have appropriate permissions in the Marq account
- Webhook events are delivered with at-least-once guarantee
- API rate limits apply to approval endpoints (100 requests per minute)
Support
For additional support:
- Email: [email protected]
- Help Center: help.marq.com
- Video Tutorials: YouTube Channel
Updated 9 days ago