> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Custom API Usage Dashboard

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Build a Custom API Usage Dashboard" description="Devin has a built-in usage dashboard, but if you need custom metrics or want to combine Devin data with other sources, have Devin build a tailored version using the v3 API." prompt="Build me an internal dashboard that shows our team's Devin usage. You can read the Devin API docs — use the v3 API consumption and metrics endpoints to pull session counts, ACU usage per user, and daily active users. Build it as a Next.js app with Recharts." category="Data & Analytics" features="API" />

<div className="uc-detail-wrapper">
  <Tip>Don't want to set this up manually? Paste a link to this page into a Devin session and ask it to set everything up for you.</Tip>

  <Steps>
    <Step title="Create a service user for API access">
      The v3 API authenticates with service user tokens, not personal API keys. You'll need to create one before Devin can pull data.

      1. Go to [app.devin.ai](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) > **Settings** > **Service Users**
      2. Click **Create Service User** and assign it a role with `ViewAccountMetrics` and `ManageBilling` permissions — these are needed to read session metrics and consumption data
      3. Copy the API token shown after creation — it's only displayed once
      4. Store the token as a [Secret](/product-guides/secrets) named `DEVIN_SERVICE_USER_TOKEN` so Devin can use it during the session without hardcoding it

      For details on service user authentication, see the [v3 API Authentication Guide](/api-reference/authentication).
    </Step>

    <Step title="Tell Devin what to build">
      Devin has native access to its own documentation through the [Devin docs MCP](/work-with-devin/mcp) — you don't need to paste the API reference into the prompt. Just point Devin at the right endpoints and it will read the docs to learn request formats, query parameters, and response shapes.

      <PromptBlock>
        ```txt Build usage dashboard theme={null}
        Build an internal dashboard that shows our team's Devin usage. Use the
        secret DEVIN_SERVICE_USER_TOKEN to authenticate. You can read the Devin
        API docs to understand the available v3 endpoints.

        Pull data from these v3 API endpoints:
        - GET /v3/enterprise/consumption/daily/organizations — ACU usage
          per org per day
        - GET /v3/enterprise/consumption/daily/users — ACU usage per user
        - GET /v3/enterprise/metrics/sessions — total session counts
        - GET /v3/enterprise/metrics/active-users — DAU/WAU/MAU

        Build it as a Next.js app with Recharts. Include:
        - Summary cards (total sessions, total ACUs, active users this week)
        - Line chart of daily ACU consumption over the past 30 days
        - Bar chart of ACU usage by user
        - Table of recent sessions with status and ACU cost

        Add a date range picker to filter all views. Include a README with
        setup and deployment instructions.
        ```
      </PromptBlock>
    </Step>

    <Step title="What Devin builds">
      Devin reads the [v3 API docs](/api-reference/v3/overview) via the docs MCP to learn the exact request formats, then scaffolds the app:

      1. **Reads the API docs** — Searches the Devin docs MCP for the consumption and metrics endpoint schemas, learning query parameters like `start_date`, `end_date`, and response shapes
      2. **Creates API routes** — Builds Next.js API routes that proxy requests to `https://api.devin.ai/v3/enterprise/*` using the service user token from the `DEVIN_SERVICE_USER_TOKEN` secret
      3. **Builds the dashboard UI** — Creates a responsive dashboard page with Recharts, including:
         * KPI cards showing total sessions, ACUs consumed, and weekly active users
         * A time-series chart of daily consumption pulled from the `/consumption/daily/organizations` endpoint
         * A per-user breakdown from `/consumption/daily/users`
         * A sessions table from the sessions list endpoint with status, duration, and ACU cost
      4. **Adds filtering** — Wires up a date range picker that re-fetches all endpoints with updated `start_date` and `end_date` params
      5. **Opens a PR** — Pushes the app with a `README.md` covering environment variables, local dev setup (`npm run dev`), and deployment to Vercel
    </Step>

    <Step title="Extend the dashboard">
      Once the base dashboard is working, ask Devin to add more panels in follow-up messages:

      <PromptBlock>
        ```txt Add org-level breakdown theme={null}
        Add a dropdown to filter the dashboard by organization. Use
        GET /v3/enterprise/organizations to populate the list, then
        scope the consumption charts to the selected org.
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Add queue health monitoring theme={null}
        Add a status indicator that shows the current session queue health.
        Use GET /v3/enterprise/queue — it returns a status of normal,
        elevated, or high. Show it as a colored badge in the header.
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Add cost estimation theme={null}
        Add a panel that estimates cost from ACU consumption. Use a
        configurable $/ACU rate stored in an environment variable. Show
        monthly cost per org and a 30-day trend line.
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
