API Integration Guide

Integrate DocInsights.io into your documentation system using our simple API endpoints and widget components.

API Endpoints

Submit Rating

POST /api/rate

{
  "rating": 8,
  "projectUid": "your-project-uid",
  "pageUrl": "https://example.com/docs/page",
  "userAgent": "Mozilla/5.0...",
  "comment": "Very helpful documentation",
  "ratingId": "optional-existing-rating-id"
}

Response Format

{
  "success": true,
  "message": "Rating submitted successfully",
  "ratingId": "rating-id-for-updates",
  "comments": ["Very helpful documentation"]
}

Custom React Widget

Build your own custom feedback widget using React and our API. Here's a complete example:

Custom Feedback Widget Component

import React, { useState } from 'react';

interface FeedbackWidgetProps {
  projectUid: string;
  pageUrl?: string;
  className?: string;
}

const FeedbackWidget: React.FC<FeedbackWidgetProps> = ({ 
  projectUid, 
  pageUrl = window.location.href,
  className = '' 
}) => {
  const [rating, setRating] = useState<number | null>(null);
  const [comment, setComment] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);

  const handleRatingSubmit = async (selectedRating: number) => {
    if (isSubmitting) return;
    
    setIsSubmitting(true);
    try {
      const response = await fetch('/api/rate', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          rating: selectedRating,
          projectUid,
          pageUrl,
          userAgent: navigator.userAgent,
          comment: comment || undefined,
        }),
      });

      if (response.ok) {
        setRating(selectedRating);
        setIsSubmitted(true);
      }
    } catch (error) {
      console.error('Failed to submit rating:', error);
    } finally {
      setIsSubmitting(false);
    }
  };

  if (isSubmitted) {
    return (
      <div className={`p-4 bg-green-50 border border-green-200 rounded-lg ${className}`}>
        <p className="text-green-800 font-medium">Thank you for your feedback!</p>
      </div>
    );
  }

  return (
    <div className={`p-6 bg-white border border-gray-200 rounded-lg shadow-sm ${className}`}>
      <h3 className="text-lg font-semibold text-gray-900 mb-4">
        How helpful was this documentation?
      </h3>
      
      <div className="mb-4">
        <div className="flex space-x-2 mb-3">
          {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((num) => (
            <button
              key={num}
              onClick={() => handleRatingSubmit(num)}
              disabled={isSubmitting}
              className={`
                w-10 h-10 rounded-full border-2 flex items-center justify-center text-sm font-medium
                ${rating === num 
                  ? 'bg-blue-600 border-blue-600 text-white' 
                  : 'border-gray-300 text-gray-700 hover:border-blue-500 hover:bg-blue-50'
                }
                ${isSubmitting ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
              `}
            >
              {num}
            </button>
          ))}
        </div>
        <div className="flex justify-between text-xs text-gray-500">
          <span>Poor</span>
          <span>Excellent</span>
        </div>
      </div>

      <div className="mb-4">
        <label htmlFor="comment" className="block text-sm font-medium text-gray-700 mb-2">
          Additional feedback (optional)
        </label>
        <textarea
          id="comment"
          value={comment}
          onChange={(e) => setComment(e.target.value)}
          rows={3}
          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
          placeholder="Tell us what could be improved or what you found helpful..."
        />
      </div>
    </div>
  );
};

export default FeedbackWidget;

Usage Example

import FeedbackWidget from './components/FeedbackWidget';

function DocumentationPage() {
  return (
    <div>
      <h1>My Documentation</h1>
      <p>Your documentation content here...</p>
      
      <FeedbackWidget 
        projectUid="your-project-uid"
        pageUrl="https://your-docs.com/this-page"
        className="mt-8"
      />
    </div>
  );
}

Advanced Features

You can extend the widget with additional features:

// Add feedback categories based on rating
const getFeedbackOptions = (rating: number) => {
  if (rating <= 6) {
    return [
      'Out of date',
      'Difficult to follow', 
      'Missing information',
      'Prefer different format'
    ];
  } else {
    return [
      'Very helpful',
      'Clear and well-written',
      'Comprehensive coverage',
      'Good examples'
    ];
  }
};

// Add multiple comment selection
const [selectedComments, setSelectedComments] = useState<string[]>([]);

const toggleComment = (comment: string) => {
  setSelectedComments(prev => 
    prev.includes(comment) 
      ? prev.filter(c => c !== comment)
      : [...prev, comment]
  );
};

Direct Feedback URLs

Create direct feedback URLs that users can visit to provide ratings:

https://your-domain.com/feedback/{projectUid}/{sourceUrl}?rating={rating}

// Examples:
https://your-domain.com/feedback/PROJECT_UID/docs/getting-started?rating=8
https://your-domain.com/feedback/PROJECT_UID/docs/api-reference?rating=3

Configuration Options

Widget Props

PropTypeRequiredDescription
projectUidstringRequiredYour project's unique identifier from the dashboard.
pageUrlstringOptionalCurrent page URL for tracking. Defaults to window.location.href.
classNamestringOptionalCustom CSS classes for styling the widget.
preSelectedRatingnumberOptionalPre-select a rating (1-10) for direct feedback links.

Feedback Options

The widget automatically shows different feedback options based on the rating:

Low Ratings (1-6)

  • • Out of date
  • • Difficult to follow
  • • Prefer a different format
  • • Missing information

High Ratings (7-10)

  • • Very helpful
  • • Clear and well-written
  • • Comprehensive coverage
  • • Good examples

CORS Support

The API supports cross-origin requests, making it easy to integrate from any domain:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

Ready to Get Started?

Create a project to get your project UID and start collecting feedback on your documentation.

Create Project

How helpful was this documentation?

PoorExcellent