Skip to Content

Moz

Category: SEO & Research
Integration type: Platform-level API key
External API: Moz JSON-RPC API v2


Purpose

Moz provides domain authority (DA), page authority (PA), and brand authority scores — industry-standard metrics for measuring a website’s relative search engine ranking strength. These scores appear in:

  • Report Writer — domain authority trend over time in monthly reports
  • Backlink Researcher — filter prospects by DA score (target DA 30–80 for link building)
  • Site Auditor — baseline DA in audit report for context
  • Dashboard — DA shown on the SEO Performance screen (D4)

Moz is a platform-level integration — one Moz API account serves all tenants. Per-query cost is tracked internally.


Config Structure

Platform config (env vars)

MOZ_ACCESS_ID=mozscape-xxxxxxxxxxxxxxxx # From moz.com → API → Access Credentials MOZ_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx MOZ_API_BASE_URL=https://api.moz.com/jsonrpc # JSON-RPC endpoint

Authentication uses HTTP Basic Auth with accessId:secretKey base64-encoded, plus a Unix timestamp and HMAC-SHA1 signed expiry:

function getMozAuthHeader(accessId: string, secretKey: string): string { const expires = Math.floor(Date.now() / 1000) + 300; // 5-minute window const signature = crypto .createHmac('sha1', secretKey) .update(`${accessId}\n${expires}`) .digest('base64'); const token = Buffer.from(`${accessId}:${expires}:${signature}`).toString('base64'); return `Basic ${token}`; }

Integration Pattern

Tool layer (packages/tools/src/moz.ts)

Moz API uses JSON-RPC over HTTPS. All requests are POST to the same endpoint with different method values:

class MozTool { constructor( private accessId: string, private secretKey: string, private baseUrl: string = 'https://api.moz.com/jsonrpc', ) {} private async call<T>(method: string, params: Record<string, any>): Promise<T> { const response = await axios.post( this.baseUrl, { jsonrpc: '2.0', id: '1', method, params }, { headers: { Authorization: getMozAuthHeader(this.accessId, this.secretKey), 'Content-Type': 'application/json', 'x-moz-token': this.accessId, }, }, ); if (response.data.error) { throw new MozApiError(response.data.error.code, response.data.error.message); } return response.data.result; } async getDomainAuthority(domain: string): Promise<DomainAuthorityResult> { const result = await this.call<any>('data.site.metrics.fetch.multiple', { data: [{ site: { query: domain, scope: 'domain' } }], data_source: 'latest', group_columns: ['site.query', 'site.scope'], index_cols: ['site.query'], metrics: [ 'site.domain_authority', 'site.page_authority', 'site.spam_score', 'site.root_domains_to_root_domain', // Number of referring domains 'site.external_links', ], }); const row = result.results[0]; return { domain: domain, domainAuthority: row['site.domain_authority'] ?? 0, pageAuthority: row['site.page_authority'] ?? 0, spamScore: row['site.spam_score'] ?? 0, referringDomains: row['site.root_domains_to_root_domain'] ?? 0, externalLinks: row['site.external_links'] ?? 0, }; } async getBrandAuthority(query: string): Promise<BrandAuthorityResult> { // Brand Authority is Moz's newer metric measuring overall brand strength in search const result = await this.call<any>('data.brand.authority.fetch', { query, scope: 'domain', }); return { brandAuthority: result.brand_authority, query, }; } async getApiQuota(): Promise<QuotaResult> { const result = await this.call<any>('data.account.limits.fetch', {}); return { rowsAvailable: result.rows_available, rowsUsed: result.rows_used, resetDate: result.reset_date, }; } async bulkGetDomainAuthority(domains: string[]): Promise<DomainAuthorityResult[]> { // Batch up to 25 domains per call (Moz API limit) const BATCH_SIZE = 25; const results: DomainAuthorityResult[] = []; for (let i = 0; i < domains.length; i += BATCH_SIZE) { const batch = domains.slice(i, i + BATCH_SIZE); const result = await this.call<any>('data.site.metrics.fetch.multiple', { data: batch.map(d => ({ site: { query: d, scope: 'domain' } })), data_source: 'latest', group_columns: ['site.query'], index_cols: ['site.query'], metrics: ['site.domain_authority', 'site.page_authority', 'site.spam_score'], }); for (const row of result.results) { results.push({ domain: row['site.query'], domainAuthority: row['site.domain_authority'] ?? 0, pageAuthority: row['site.page_authority'] ?? 0, spamScore: row['site.spam_score'] ?? 0, }); } } return results; } async verify(): Promise<void> { await this.getApiQuota(); } }
// Inside backlink-researcher worker — after generating prospects const domains = prospects.map(p => p.domain); const daScores = await mozTool.bulkGetDomainAuthority(domains); const daMap = Object.fromEntries(daScores.map(r => [r.domain, r.domainAuthority])); const qualified = prospects .map(p => ({ ...p, da: daMap[p.domain] ?? 0 })) .filter(p => p.da >= 30 && p.da <= 80); // Sweet spot for link building

DA vs PA vs Brand Authority

MetricRangeWhat it measures
Domain Authority (DA)1–100Entire domain’s search ranking strength
Page Authority (PA)1–100Individual page’s ranking strength
Spam Score0–100Likelihood of penalisation by Google
Brand Authority0–100Overall brand strength in organic search (Moz’s newer metric)

DA and PA are logarithmic — moving from 20 to 30 is much easier than moving from 70 to 80.


API Row Credits

Moz API usage is metered in row credits. Each domain queried costs 1 row credit. Monthly allocation depends on the Moz API plan. The platform checks the quota via getApiQuota() before bulk operations.


Test Cases

Unit tests (packages/tools/src/moz.test.ts)

TestApproach
getDomainAuthority() builds correct JSON-RPC payloadMock axios.post; assert method, params.metrics array
getDomainAuthority() maps result row to typed objectMock result with site.domain_authority: 45; assert domainAuthority === 45
getBrandAuthority() calls correct methodAssert method === 'data.brand.authority.fetch'
bulkGetDomainAuthority() batches in groups of 25Pass 30 domains; assert two API calls (25 + 5)
HMAC-SHA1 auth header computed correctlyAssert header format Basic base64(accessId:expires:sig)
verify() calls getApiQuotaAssert quota endpoint called
Throws MozApiError on error responseMock { error: { code: 401, message: 'Unauthorized' } }

© 2026 Leadmetrics — Internal use only