agentsclimarketplace

Grammarly upgrade migration

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/grammarly-pack/skills/grammarly-upgrade-migration

'Upgrade and migration guidance for Grammarly API version changes. Use when migratingFrom its SKILL.md

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill grammarly-upgrade-migration

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

5.9 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it

Grammarly Upgrade & Migration

Overview

Grammarly exposes versioned APIs for writing analysis, AI detection, and plagiarism checking. Each API family versions independently — the Writing Score API may be on v2 while AI Detection remains on v1. Tracking these versions matters because Grammarly deprecates older API versions on a fixed timeline, and the response schemas differ significantly between versions (score breakdowns, suggestion categories, and confidence thresholds all change). Missing a version cutover means silent failures or degraded writing feedback quality.

Version Detection

const GRAMMARLY_BASE = "https://api.grammarly.com/ecosystem/api";

interface GrammarlyVersionMap {
  scores: string;
  aiDetection: string;
  plagiarism: string;
  latestAvailable: Record<string, string>;
}

async function detectGrammarlyVersions(apiKey: string): Promise<GrammarlyVersionMap> {
  const endpoints = {
    scores: `${GRAMMARLY_BASE}/v2/scores`,
    aiDetection: `${GRAMMARLY_BASE}/v1/ai-detection`,
    plagiarism: `${GRAMMARLY_BASE}/v1/plagiarism`,
  };

  const versions: Record<string, string> = {};
  for (const [api, url] of Object.entries(endpoints)) {
    const res = await fetch(url, {
      method: "HEAD",
      headers: { Authorization: `Bearer ${apiKey}` },
    });
    versions[api] = res.headers.get("x-grammarly-api-version") ?? "unknown";
    const deprecated = res.headers.get("x-grammarly-deprecated");
    if (deprecated) console.warn(`${api} endpoint deprecated: ${deprecated}`);
  }
  return { scores: "v2", aiDetection: "v1", plagiarism: "v1", latestAvailable: versions };
}

Migration Checklist

  • Audit codebase for all api.grammarly.com endpoint references
  • Map each endpoint to its current API version (v1 vs. v2)
  • Check if Writing Score v2 response includes new sub-score categories
  • Verify AI Detection confidence threshold changes between versions
  • Update plagiarism check response parser if source attribution format changed
  • Test OAuth token flow — scope names may differ between API versions
  • Validate suggestion category enums (clarity, engagement, delivery, correctness)
  • Update error handling for new rate limit headers in v2
  • Check if text submission size limits changed between versions
  • Run A/B comparison of v1 vs. v2 scores on sample corpus to verify parity

Schema Migration

// Grammarly scores response changed from flat scores to structured breakdown
interface OldScoreResponse {
  overall: number;
  correctness: number;
  clarity: number;
  engagement: number;
  delivery: number;
}

interface NewScoreResponse {
  overall: { score: number; label: string };
  dimensions: Array<{
    name: "correctness" | "clarity" | "engagement" | "delivery";
    score: number;
    label: string;
    suggestions: Array<{ category: string; message: string; severity: "critical" | "warning" | "info" }>;
  }>;
  metadata: { wordCount: number; readingTime: number; apiVersion: string };
}

function migrateScoreResponse(old: OldScoreResponse): NewScoreResponse {
  const toLabel = (s: number) => (s >= 80 ? "Strong" : s >= 60 ? "Good" : "Needs work");
  return {
    overall: { score: old.overall, label: toLabel(old.overall) },
    dimensions: (["correctness", "clarity", "engagement", "delivery"] as const).map((name) => ({
      name,
      score: old[name],
      label: toLabel(old[name]),
      suggestions: [],
    })),
    metadata: { wordCount: 0, readingTime: 0, apiVersion: "v1-migrated" },
  };
}

Rollback Strategy

class GrammarlyClient {
  private versionMap: Record<string, string> = { scores: "v2", aiDetection: "v1", plagiarism: "v1" };
  private fallbackMap: Record<string, string> = { scores: "v1", aiDetection: "v1", plagiarism: "v1" };

  constructor(private apiKey: string) {}

  async checkText(text: string, api: "scores" | "aiDetection" | "plagiarism"): Promise<any> {
    const version = this.versionMap[api];
    try {
      const res = await fetch(`https://api.grammarly.com/ecosystem/api/${version}/${api}`, {
        method: "POST",
        headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
        body: JSON.stringify({ text }),
      });
      if (!res.ok) throw new Error(`Grammarly ${api} ${res.status}`);
      return await res.json();
    } catch (err) {
      const fallback = this.fallbackMap[api];
      if (fallback !== version) {
        console.warn(`Falling back ${api} from ${version} to ${fallback}`);
        this.versionMap[api] = fallback;
        return this.checkText(text, api);
      }
      throw err;
    }
  }
}

Error Handling

Migration IssueSymptomFix
Score dimension renamedResponse missing engagement, has tone insteadUpdate parser to map new dimension names to internal schema
API version sunset410 Gone on v1 scores endpointMigrate all calls to v2 and update response parsing
OAuth scope mismatch403 after upgrading API versionRe-authorize with scopes matching new version requirements
Text length limit changed413 Payload Too Large on previously working requestsChunk text into smaller segments per new version limits
Rate limit structure changed429 without X-RateLimit-Reset headerSwitch to Retry-After header or implement exponential backoff

Resources

Next Steps

For CI pipeline integration, see grammarly-ci-integration.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.