{"id":"2455d846-dd93-4ca8-ae69-3b1dc2806e6d","shortId":"KgK9Ux","kind":"skill","title":"azure-ai-contentsafety-ts","tagline":"Analyze text and images for harmful content with customizable blocklists.","description":"# Azure AI Content Safety REST SDK for TypeScript\n\nAnalyze text and images for harmful content with customizable blocklists.\n\n## Installation\n\n```bash\nnpm install @azure-rest/ai-content-safety @azure/identity @azure/core-auth\n```\n\n## Environment Variables\n\n```bash\nCONTENT_SAFETY_ENDPOINT=https://<resource>.cognitiveservices.azure.com\nCONTENT_SAFETY_KEY=<api-key>\n```\n\n## Authentication\n\n**Important**: This is a REST client. `ContentSafetyClient` is a **function**, not a class.\n\n### API Key\n\n```typescript\nimport ContentSafetyClient from \"@azure-rest/ai-content-safety\";\nimport { AzureKeyCredential } from \"@azure/core-auth\";\n\nconst client = ContentSafetyClient(\n  process.env.CONTENT_SAFETY_ENDPOINT!,\n  new AzureKeyCredential(process.env.CONTENT_SAFETY_KEY!)\n);\n```\n\n### DefaultAzureCredential\n\n```typescript\nimport ContentSafetyClient from \"@azure-rest/ai-content-safety\";\nimport { DefaultAzureCredential } from \"@azure/identity\";\n\nconst client = ContentSafetyClient(\n  process.env.CONTENT_SAFETY_ENDPOINT!,\n  new DefaultAzureCredential()\n);\n```\n\n## Analyze Text\n\n```typescript\nimport ContentSafetyClient, { isUnexpected } from \"@azure-rest/ai-content-safety\";\n\nconst result = await client.path(\"/text:analyze\").post({\n  body: {\n    text: \"Text content to analyze\",\n    categories: [\"Hate\", \"Sexual\", \"Violence\", \"SelfHarm\"],\n    outputType: \"FourSeverityLevels\"  // or \"EightSeverityLevels\"\n  }\n});\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\nfor (const analysis of result.body.categoriesAnalysis) {\n  console.log(`${analysis.category}: severity ${analysis.severity}`);\n}\n```\n\n## Analyze Image\n\n### Base64 Content\n\n```typescript\nimport { readFileSync } from \"node:fs\";\n\nconst imageBuffer = readFileSync(\"./image.png\");\nconst base64Image = imageBuffer.toString(\"base64\");\n\nconst result = await client.path(\"/image:analyze\").post({\n  body: {\n    image: { content: base64Image }\n  }\n});\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\nfor (const analysis of result.body.categoriesAnalysis) {\n  console.log(`${analysis.category}: severity ${analysis.severity}`);\n}\n```\n\n### Blob URL\n\n```typescript\nconst result = await client.path(\"/image:analyze\").post({\n  body: {\n    image: { blobUrl: \"https://storage.blob.core.windows.net/container/image.png\" }\n  }\n});\n```\n\n## Blocklist Management\n\n### Create Blocklist\n\n```typescript\nconst result = await client\n  .path(\"/text/blocklists/{blocklistName}\", \"my-blocklist\")\n  .patch({\n    contentType: \"application/merge-patch+json\",\n    body: {\n      description: \"Custom blocklist for prohibited terms\"\n    }\n  });\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\nconsole.log(`Created: ${result.body.blocklistName}`);\n```\n\n### Add Items to Blocklist\n\n```typescript\nconst result = await client\n  .path(\"/text/blocklists/{blocklistName}:addOrUpdateBlocklistItems\", \"my-blocklist\")\n  .post({\n    body: {\n      blocklistItems: [\n        { text: \"prohibited-term-1\", description: \"First blocked term\" },\n        { text: \"prohibited-term-2\", description: \"Second blocked term\" }\n      ]\n    }\n  });\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\nfor (const item of result.body.blocklistItems ?? []) {\n  console.log(`Added: ${item.blocklistItemId}`);\n}\n```\n\n### Analyze with Blocklist\n\n```typescript\nconst result = await client.path(\"/text:analyze\").post({\n  body: {\n    text: \"Text that might contain blocked terms\",\n    blocklistNames: [\"my-blocklist\"],\n    haltOnBlocklistHit: false\n  }\n});\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\n// Check blocklist matches\nif (result.body.blocklistsMatch) {\n  for (const match of result.body.blocklistsMatch) {\n    console.log(`Blocked: \"${match.blocklistItemText}\" from ${match.blocklistName}`);\n  }\n}\n```\n\n### List Blocklists\n\n```typescript\nconst result = await client.path(\"/text/blocklists\").get();\n\nif (isUnexpected(result)) {\n  throw result.body;\n}\n\nfor (const blocklist of result.body.value ?? []) {\n  console.log(`${blocklist.blocklistName}: ${blocklist.description}`);\n}\n```\n\n### Delete Blocklist\n\n```typescript\nawait client.path(\"/text/blocklists/{blocklistName}\", \"my-blocklist\").delete();\n```\n\n## Harm Categories\n\n| Category | API Term | Description |\n|----------|----------|-------------|\n| Hate and Fairness | `Hate` | Discriminatory language targeting identity groups |\n| Sexual | `Sexual` | Sexual content, nudity, pornography |\n| Violence | `Violence` | Physical harm, weapons, terrorism |\n| Self-Harm | `SelfHarm` | Self-injury, suicide, eating disorders |\n\n## Severity Levels\n\n| Level | Risk | Recommended Action |\n|-------|------|-------------------|\n| 0 | Safe | Allow |\n| 2 | Low | Review or allow with warning |\n| 4 | Medium | Block or require human review |\n| 6 | High | Block immediately |\n\n**Output Types**:\n- `FourSeverityLevels` (default): Returns 0, 2, 4, 6\n- `EightSeverityLevels`: Returns 0-7\n\n## Content Moderation Helper\n\n```typescript\nimport ContentSafetyClient, { \n  isUnexpected, \n  TextCategoriesAnalysisOutput \n} from \"@azure-rest/ai-content-safety\";\n\ninterface ModerationResult {\n  isAllowed: boolean;\n  flaggedCategories: string[];\n  maxSeverity: number;\n  blocklistMatches: string[];\n}\n\nasync function moderateContent(\n  client: ReturnType<typeof ContentSafetyClient>,\n  text: string,\n  maxAllowedSeverity = 2,\n  blocklistNames: string[] = []\n): Promise<ModerationResult> {\n  const result = await client.path(\"/text:analyze\").post({\n    body: { text, blocklistNames, haltOnBlocklistHit: false }\n  });\n\n  if (isUnexpected(result)) {\n    throw result.body;\n  }\n\n  const flaggedCategories = result.body.categoriesAnalysis\n    .filter(c => (c.severity ?? 0) > maxAllowedSeverity)\n    .map(c => c.category!);\n\n  const maxSeverity = Math.max(\n    ...result.body.categoriesAnalysis.map(c => c.severity ?? 0)\n  );\n\n  const blocklistMatches = (result.body.blocklistsMatch ?? [])\n    .map(m => m.blocklistItemText!);\n\n  return {\n    isAllowed: flaggedCategories.length === 0 && blocklistMatches.length === 0,\n    flaggedCategories,\n    maxSeverity,\n    blocklistMatches\n  };\n}\n```\n\n## API Endpoints\n\n| Operation | Method | Path |\n|-----------|--------|------|\n| Analyze Text | POST | `/text:analyze` |\n| Analyze Image | POST | `/image:analyze` |\n| Create/Update Blocklist | PATCH | `/text/blocklists/{blocklistName}` |\n| List Blocklists | GET | `/text/blocklists` |\n| Delete Blocklist | DELETE | `/text/blocklists/{blocklistName}` |\n| Add Blocklist Items | POST | `/text/blocklists/{blocklistName}:addOrUpdateBlocklistItems` |\n| List Blocklist Items | GET | `/text/blocklists/{blocklistName}/blocklistItems` |\n| Remove Blocklist Items | POST | `/text/blocklists/{blocklistName}:removeBlocklistItems` |\n\n## Key Types\n\n```typescript\nimport ContentSafetyClient, {\n  isUnexpected,\n  AnalyzeTextParameters,\n  AnalyzeImageParameters,\n  TextCategoriesAnalysisOutput,\n  ImageCategoriesAnalysisOutput,\n  TextBlocklist,\n  TextBlocklistItem\n} from \"@azure-rest/ai-content-safety\";\n```\n\n## Best Practices\n\n1. **Always use isUnexpected()** - Type guard for error handling\n2. **Set appropriate thresholds** - Different categories may need different severity thresholds\n3. **Use blocklists for domain-specific terms** - Supplement AI detection with custom rules\n4. **Log moderation decisions** - Keep audit trail for compliance\n5. **Handle edge cases** - Empty text, very long text, unsupported image formats\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["azure","contentsafety","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-azure-ai-contentsafety-ts","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/azure-ai-contentsafety-ts","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34964 github stars · SKILL.md body (7,757 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-25T00:50:30.744Z","embedding":null,"createdAt":"2026-04-18T21:31:52.526Z","updatedAt":"2026-04-25T00:50:30.744Z","lastSeenAt":"2026-04-25T00:50:30.744Z","tsv":"'-7':458 '/ai-content-safety':41,77,101,124,471,610 '/blocklistitems':586 '/container/image.png':219 '/image':183,211,557 '/image.png':174 '/text':129,312,498,552 '/text/blocklists':230,264,356,376,562,567,571,577,584,591 '0':425,451,457,517,528,538,540 '1':277,613 '2':286,428,452,490,622 '3':633 '4':435,453,647 '5':656 '6':442,454 'action':424,680 'ad':302 'add':254,573 'addorupdateblocklistitem':266,579 'ai':3,17,642 'allow':427,432 'alway':614 'analysi':154,197 'analysis.category':158,201 'analysis.severity':160,203 'analyz':6,24,114,130,137,161,184,212,304,313,499,549,553,554,558 'analyzeimageparamet':601 'analyzetextparamet':600 'api':68,385,544 'applic':674 'application/merge-patch':237 'appropri':624 'ask':718 'async':482 'audit':652 'authent':54 'await':127,181,209,227,261,310,354,374,496 'azur':2,16,39,75,99,122,469,608 'azure-ai-contentsafety-t':1 'azure-rest':38,74,98,121,468,607 'azure/core-auth':43,81 'azure/identity':42,105 'azurekeycredenti':79,89 'base64':163,178 'base64image':176,189 'bash':35,46 'best':611 'blob':204 'bloburl':216 'block':280,289,321,345,437,444 'blocklist':15,33,220,223,234,242,257,269,306,326,335,350,365,372,380,560,565,569,574,581,588,635 'blocklist.blocklistname':369 'blocklist.description':370 'blocklistitem':272 'blocklistmatch':480,530,543 'blocklistmatches.length':539 'blocklistnam':231,265,323,377,491,503,563,572,578,585,592 'bodi':132,186,214,239,271,315,501 'boolean':475 'boundari':726 'c':515,520,526 'c.category':521 'c.severity':516,527 'case':659 'categori':138,383,384,627 'check':334 'clarif':720 'class':67 'clear':693 'client':60,83,107,228,262,485 'client.path':128,182,210,311,355,375,497 'cognitiveservices.azure.com':50 'complianc':655 'console.log':157,200,251,301,344,368 'const':82,106,125,153,171,175,179,196,207,225,259,297,308,340,352,364,494,511,522,529 'contain':320 'content':12,18,30,47,51,135,164,188,400,459 'contentsafeti':4 'contentsafetycli':61,72,84,96,108,118,464,598 'contenttyp':236 'creat':222,252 'create/update':559 'criteria':729 'custom':241,645 'customiz':14,32 'decis':650 'default':449 'defaultazurecredenti':93,103,113 'delet':371,381,568,570 'describ':681,697 'descript':240,278,287,387 'detect':643 'differ':626,630 'discriminatori':392 'disord':418 'domain':638 'domain-specif':637 'eat':417 'edg':658 'eightseveritylevel':146,455 'empti':660 'endpoint':49,87,111,545 'environ':44,709 'environment-specif':708 'error':620 'execut':676 'expert':714 'fair':390 'fals':328,505 'filter':514 'first':279 'flaggedcategori':476,512,541 'flaggedcategories.length':537 'format':667 'fourseveritylevel':144,448 'fs':170 'function':64,483 'get':357,566,583 'group':396 'guard':618 'haltonblocklisthit':327,504 'handl':621,657 'harm':11,29,382,406,411 'hate':139,388,391 'helper':461 'high':443 'human':440 'ident':395 'imag':9,27,162,187,215,555,666 'imagebuff':172 'imagebuffer.tostring':177 'imagecategoriesanalysisoutput':603 'immedi':445 'import':55,71,78,95,102,117,166,463,597 'injuri':415 'input':723 'instal':34,37 'interfac':472 'isallow':474,536 'isunexpect':119,148,191,247,292,330,359,465,507,599,616 'item':255,298,575,582,589 'item.blocklistitemid':303 'json':238 'keep':651 'key':53,69,92,594 'languag':393 'level':420,421 'limit':685 'list':349,564,580 'log':648 'long':663 'low':429 'm':533 'm.blocklistitemtext':534 'manag':221 'map':519,532 'match':336,341,694 'match.blocklistitemtext':346 'match.blocklistname':348 'math.max':524 'maxallowedsever':489,518 'maxsever':478,523,542 'may':628 'medium':436 'method':547 'might':319 'miss':731 'moder':460,649 'moderatecont':484 'moderationresult':473 'my-blocklist':232,267,324,378 'need':629 'new':88,112 'node':169 'npm':36 'nuditi':401 'number':479 'oper':546 'output':446,703 'outputtyp':143 'overview':684 'patch':235,561 'path':229,263,548 'permiss':724 'physic':405 'pornographi':402 'post':131,185,213,270,314,500,551,556,576,590 'practic':612 'process.env.content':85,90,109 'prohibit':244,275,284 'prohibited-term':274,283 'promis':493 'readfilesync':167,173 'recommend':423 'remov':587 'removeblocklistitem':593 'requir':439,722 'rest':20,40,59,76,100,123,470,609 'result':126,149,180,192,208,226,248,260,293,309,331,353,360,495,508 'result.body':151,194,250,295,333,362,510 'result.body.blocklistitems':300 'result.body.blocklistname':253 'result.body.blocklistsmatch':338,343,531 'result.body.categoriesanalysis':156,199,513 'result.body.categoriesanalysis.map':525 'result.body.value':367 'return':450,456,535 'returntyp':486 'review':430,441,715 'risk':422 'rule':646 'safe':426 'safeti':19,48,52,86,91,110,725 'scope':696 'sdk':21 'second':288 'self':410,414 'self-harm':409 'self-injuri':413 'selfharm':142,412 'set':623 'sever':159,202,419,631 'sexual':140,397,398,399 'skill':672,688 'skill-azure-ai-contentsafety-ts' 'source-sickn33' 'specif':639,710 'stop':716 'storage.blob.core.windows.net':218 'storage.blob.core.windows.net/container/image.png':217 'string':477,481,488,492 'substitut':706 'success':728 'suicid':416 'supplement':641 'target':394 'task':692 'term':245,276,281,285,290,322,386,640 'terror':408 'test':712 'text':7,25,115,133,134,273,282,316,317,487,502,550,661,664 'textblocklist':604 'textblocklistitem':605 'textcategoriesanalysisoutput':466,602 'threshold':625,632 'throw':150,193,249,294,332,361,509 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'trail':653 'treat':701 'ts':5 'type':447,595,617 'typescript':23,70,94,116,165,206,224,258,307,351,373,462,596 'unsupport':665 'url':205 'use':615,634,670,686 'valid':711 'variabl':45 'violenc':141,403,404 'warn':434 'weapon':407 'workflow':678","prices":[{"id":"5b8c4cc9-ab4e-4cce-98c0-29647dfaa0ee","listingId":"2455d846-dd93-4ca8-ae69-3b1dc2806e6d","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:31:52.526Z"}],"sources":[{"listingId":"2455d846-dd93-4ca8-ae69-3b1dc2806e6d","source":"github","sourceId":"sickn33/antigravity-awesome-skills/azure-ai-contentsafety-ts","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azure-ai-contentsafety-ts","isPrimary":false,"firstSeenAt":"2026-04-18T21:31:52.526Z","lastSeenAt":"2026-04-25T00:50:30.744Z"}],"details":{"listingId":"2455d846-dd93-4ca8-ae69-3b1dc2806e6d","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"azure-ai-contentsafety-ts","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34964,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-24T06:41:17Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"d9b6b1bf14a7a3f7e04e5c1f4b690efa0ce95aea","skill_md_path":"skills/azure-ai-contentsafety-ts/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azure-ai-contentsafety-ts"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"azure-ai-contentsafety-ts","description":"Analyze text and images for harmful content with customizable blocklists."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/azure-ai-contentsafety-ts"},"updatedAt":"2026-04-25T00:50:30.744Z"}}