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:

  1. Approval Requests: Initiated when content needs review
  2. Approval Targets: The content being reviewed (projects, templates)
  3. Approvers: Users with permission to approve or decline requests
  4. Approval States: Current status of the approval process

Approval Flow

Project Created → Approval Request → Pending Review → Approved/Declined → Final State

Approval States

StateDescriptionNext Actions
pending_approvalAwaiting reviewer actionApprove or decline
approvedContent has been approvedContent can be published/used
declinedContent has been rejectedRequires 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 approval
  • approverId (optional): Filter by assigned approver
  • approvalTarget (optional): Filter by specific content ID
  • approvalState (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 approver
  • approvalState: 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 CodeDescriptionResolution
401UnauthorizedVerify access token is valid
403ForbiddenCheck user permissions
404Not FoundVerify project/approval ID exists
422Validation ErrorCheck required parameters
429Rate LimitedImplement 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: