Skip to main content
miro-sdk-patterns Apply production-ready patterns for @mirohq/miro-api client usage.
Use when implementing Miro integrations, refactoring SDK usage,
or establishing coding standards for Miro REST API v2.
Trigger with phrases like "miro SDK patterns", "miro best practices",
"miro code patterns", "miro client wrapper", "miro typescript".
Zur Installation springen Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill miro-sdk-patternsDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation
name miro-sdk-patterns description Apply production-ready patterns for @mirohq/miro-api client usage.
Use when implementing Miro integrations, refactoring SDK usage,
or establishing coding standards for Miro REST API v2.
Trigger with phrases like "miro SDK patterns", "miro best practices",
"miro code patterns", "miro client wrapper", "miro typescript".
allowed-tools Read, Write, Edit version 1.6.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","miro","patterns","typescript"] compatibility Designed for Claude Code
Miro SDK Patterns
Overview
Production-ready patterns for the @mirohq/miro-api Node.js client and direct REST API v2 usage. Covers the high-level Miro client (stateful, OAuth-aware) and the low-level MiroApi client (stateless, token-based).
Prerequisites
@mirohq/miro-api installed
TypeScript 5+ project
Understanding of Miro REST API v2 item model
Two Client Modes
import { Miro , MiroApi } from '@mirohq/miro-api' ;
const miro = new Miro ({
clientId : process.env .MIRO_CLIENT_ID !,
clientSecret : process.env .MIRO_CLIENT_SECRET !,
redirectUrl : process.env .MIRO_REDIRECT_URI !,
});
const userApi = await miro.as ('user-id' );
const api = new MiroApi (process.env .MIRO_ACCESS_TOKEN !);
Pattern 1: Type-Safe Board Service
import { MiroApi } from '@mirohq/miro-api' ;
{
: ;
: ;
: ;
: ;
: ;
: ;
}
{
: ;
: | | | | | | | | ;
: < , >;
: { : ; : ; : };
?: { ?: ; ?: };
: ;
: { : ; : };
}
<T> {
: T[];
: ;
: ;
: ;
: ;
?: ;
}
{
( ) {}
( : ): < > {
response = . . (boardId);
response. ;
}
(
: ,
: { ?: ; ?: ; ?: } = {}
): < < >> {
params = ();
(options. ) params. ( , options. );
(options. ) params. ( , (options. ));
(options. ) params. ( , options. );
response = (
,
{ : . () }
);
response. ();
}
( : ): < []> {
: [] = [];
: | ;
{
page = . (boardId, { : , cursor });
items. (...page. );
cursor = page. ;
} (cursor);
items;
}
( ) {
{
: ,
: ,
};
}
}
interface
MiroBoard
id
string
type
'board'
name
string
description
string
createdAt
string
modifiedAt
string
interface
MiroBoardItem
id
string
type
'sticky_note'
'shape'
'card'
'text'
'frame'
'image'
'document'
'embed'
'app_card'
data
Record
string
unknown
position
x
number
y
number
origin
string
geometry
width
number
height
number
createdAt
string
createdBy
id
string
type
string
interface
PaginatedResponse
data
total
number
size
number
offset
number
limit
number
cursor
string
export
class
BoardService
constructor
private api : MiroApi
async
getBoard
boardId
string
Promise
MiroBoard
const
await
this
api
getBoard
return
body
as
unknown
as
MiroBoard
async
listItems
boardId
string
options
type
string
limit
number
cursor
string
Promise
PaginatedResponse
MiroBoardItem
const
new
URLSearchParams
if
type
set
'type'
type
if
limit
set
'limit'
String
limit
if
cursor
set
'cursor'
cursor
const
await
fetch
`https://api.miro.com/v2/boards/${boardId} /items?${params} `
headers
this
authHeaders
return
json
async
getAllItems
boardId
string
Promise
MiroBoardItem
const
items
MiroBoardItem
let
cursor
string
undefined
do
const
await
this
listItems
limit
50
push
data
cursor
while
return
private
authHeaders
return
'Authorization'
`Bearer ${process.env.MIRO_ACCESS_TOKEN} `
'Content-Type'
'application/json'
Pattern 2: Item Factory
type StickyNoteColor = 'light_yellow' | 'light_green' | 'light_blue'
| 'light_pink' | 'gray' | 'light_cyan' | 'light_orange' ;
interface CreateStickyNoteParams {
boardId : string ;
content : string ;
color ?: StickyNoteColor ;
x ?: number ;
y ?: number ;
width ?: number ;
}
interface CreateShapeParams {
boardId : string ;
content : string ;
shape ?: 'rectangle' | 'circle' | 'triangle' | 'rhombus'
| 'round_rectangle' | 'parallelogram' | 'star'
| 'right_arrow' | 'left_arrow' | 'pentagon' | 'hexagon'
| 'octagon' | 'trapezoid' | 'flow_chart_predefined_process'
| 'can' | 'cross' | 'cloud' ;
fillColor ?: string ;
x ?: number ;
y ?: number ;
width ?: number ;
height ?: number ;
}
interface CreateCardParams {
boardId : string ;
title : string ;
description ?: string ;
dueDate ?: string ;
assigneeId ?: string ;
x ?: number ;
y ?: number ;
}
export class ItemFactory {
constructor (private token : string ) {}
async createStickyNote (params : CreateStickyNoteParams ): Promise <MiroBoardItem > {
return this .post (`/v2/boards/${params.boardId} /sticky_notes` , {
data : { content : params.content , shape : 'square' },
style : { fillColor : params.color ?? 'light_yellow' , textAlign : 'center' },
position : { x : params.x ?? 0 , y : params.y ?? 0 },
geometry : { width : params.width ?? 199 },
});
}
async createShape (params : CreateShapeParams ): Promise <MiroBoardItem > {
return this .post (`/v2/boards/${params.boardId} /shapes` , {
data : { content : params.content , shape : params.shape ?? 'round_rectangle' },
style : { fillColor : params.fillColor ?? '#4262ff' , textAlign : 'center' },
position : { x : params.x ?? 0 , y : params.y ?? 0 },
geometry : { width : params.width ?? 200 , height : params.height ?? 100 },
});
}
async createCard (params : CreateCardParams ): Promise <MiroBoardItem > {
return this .post (`/v2/boards/${params.boardId} /cards` , {
data : {
title : params.title ,
description : params.description ,
dueDate : params.dueDate ,
assigneeId : params.assigneeId ,
},
position : { x : params.x ?? 0 , y : params.y ?? 0 },
});
}
private async post (path : string , body : unknown ): Promise <MiroBoardItem > {
const res = await fetch (`https://api.miro.com${path} ` , {
method : 'POST' ,
headers : {
'Authorization' : `Bearer ${this .token} ` ,
'Content-Type' : 'application/json' ,
},
body : JSON .stringify (body),
});
if (!res.ok ) {
const err = await res.json ();
throw new MiroApiError (res.status , err.message ?? 'API request failed' , err.code );
}
return res.json ();
}
}
Pattern 3: Error Handling Wrapper
export class MiroApiError extends Error {
constructor (
public readonly status : number ,
message : string ,
public readonly code ?: string ,
) {
super (message);
this .name = 'MiroApiError' ;
}
get isRetryable (): boolean {
return this .status === 429 || (this .status >= 500 && this .status < 600 );
}
get isAuthError (): boolean {
return this .status === 401 || this .status === 403 ;
}
}
async function safeMiroCall<T>(
operation : () => Promise <T>,
context : string
): Promise <{ data : T | null ; error : MiroApiError | null }> {
try {
const data = await operation ();
return { data, error : null };
} catch (err) {
if (err instanceof MiroApiError ) {
console .error (`[Miro:${context} ] ${err.status} : ${err.message} ` );
return { data : null , error : err };
}
throw err;
}
}
Pattern 4: Multi-Tenant Client Factory
import { Miro , MiroApi } from '@mirohq/miro-api' ;
const clients = new Map <string , MiroApi >();
export async function getClientForUser (userId : string ): Promise <MiroApi > {
if (!clients.has (userId)) {
const miro = new Miro ({
clientId : process.env .MIRO_CLIENT_ID !,
clientSecret : process.env .MIRO_CLIENT_SECRET !,
redirectUrl : process.env .MIRO_REDIRECT_URI !,
});
if (!await miro.isAuthorized (userId)) {
throw new Error (`User ${userId} has not authorized Miro` );
}
const api = await miro.as (userId);
clients.set (userId, api);
}
return clients.get (userId)!;
}
Pattern 5: Response Validation with Zod import { z } from 'zod' ;
const MiroBoardSchema = z.object ({
id : z.string (),
type : z.literal ('board' ),
name : z.string (),
description : z.string ().optional (),
createdAt : z.string ().datetime (),
modifiedAt : z.string ().datetime (),
});
const MiroItemSchema = z.object ({
id : z.string (),
type : z.enum (['sticky_note' , 'shape' , 'card' , 'text' , 'frame' , 'image' , 'document' , 'embed' , 'app_card' ]),
data : z.record (z.unknown ()),
position : z.object ({ x : z.number (), y : z.number () }),
});
function validateBoardResponse (data : unknown ) {
return MiroBoardSchema .parse (data);
}
Error Handling Pattern Use Case Benefit Type-safe service Board/item CRUD Catches shape mismatches at compile time Item factory Bulk item creation Consistent defaults, validated params Error wrapper All API calls Classifies errors as retryable vs auth vs input Multi-tenant SaaS applications Isolates users, manages token lifecycle Zod validation Response parsing Runtime safety against API changes
Resources
Next Steps Apply these patterns in miro-core-workflow-a for board management operations.