Skip to content
Back to skills

389 Api F9daa528

ASecurity

```typescript // step.do() const result = await step.do('step name', async () => { /* logic */ }); const result = await step.do('step name', { retries, timeout }, async () => {});

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
securitytypescriptbashapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 389-api_f9daa528 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 389 Api F9daa528?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 389 Api F9daa528
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-389-api-f9daa528/badge)](https://www.skillsdirectory.com/skills/tools-only-389-api-f9daa528)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Workflow APIs

## Step APIs

```typescript
// step.do()
const result = await step.do('step name', async () => { /* logic */ });
const result = await step.do('step name', { retries, timeout }, async () => {});

// step.sleep()
await step.sleep('description', '1 hour');
await step.sleep('description', 5000); // ms

// step.sleepUntil()
await step.sleepUntil('description', Date.parse('2024-12-31'));

// step.waitForEvent()
const data = await step.waitForEvent<PayloadType>('wait', {event: 'webhook-type', timeout: '24h'}); // Default 24h, max 365d
try { const event = await step.waitForEvent('wait', { event: 'approval', timeout: '1h' }); } catch (e) { /* Timeout */ }
```

## Instance Management

```typescript
// Create single
const instance = await env.MY_WORKFLOW.create({id: crypto.randomUUID(), params: { userId: 'user123' }}); // id optional, auto-generated if omitted

// Create with custom retention (default: 3 days free, 30 days paid)
const instance = await env.MY_WORKFLOW.create({
  id: crypto.randomUUID(),
  params: { userId: 'user123' },
  retention: '30 days'  // Override default retention period
});

// Batch (max 100, idempotent: skips existing IDs)
const instances = await env.MY_WORKFLOW.createBatch([{id: 'user1', params: {name: 'John'}}, {id: 'user2', params: {name: 'Jane'}}]);

// Get & Status
const instance = await env.MY_WORKFLOW.get('instance-id');
const status = await instance.status(); // {status: 'queued' | 'running' | 'paused' | 'errored' | 'terminated' | 'complete' | 'waiting' | 'waitingForPause' | 'unknown', error?, output?}

// Control
await instance.pause(); await instance.resume(); await instance.terminate(); await instance.restart();

// Send Events
await instance.sendEvent({type: 'approval', payload: { approved: true }}); // Must match waitForEvent type
```

## Triggering Workflows

```typescript
// From Worker
export default { async fetch(req, env) { const instance = await env.MY_WORKFLOW.create({id: crypto.randomUUID(), params: { userId: 'user123' }}); return Response.json({ id: instance.id }); }};

// From Queue
export default { async queue(batch, env) { for (const msg of batch.messages) { await env.MY_WORKFLOW.create({id: `job-${msg.id}`, params: msg.body}); } }};

// From Cron
export default { async scheduled(event, env) { await env.CLEANUP_WORKFLOW.create({id: `cleanup-${Date.now()}`, params: { timestamp: event.scheduledTime }}); }};

// From Another Workflow (non-blocking)
export class ParentWorkflow extends WorkflowEntrypoint<Env, Params> {
  async run(event, step) {
    const child = await step.do('start child', async () => await this.env.CHILD_WORKFLOW.create({id: `child-${event.instanceId}`, params: {}}));
  }
}
```

## Error Handling

```typescript
import { NonRetryableError } from 'cloudflare:workers';

// NonRetryableError
await step.do('validate', async () => {
  if (!event.params.paymentMethod) throw new NonRetryableError('Payment method required');
  const res = await fetch('https://api.example.com/charge', { method: 'POST' });
  if (res.status === 401) throw new NonRetryableError('Invalid credentials'); // Don't retry
  if (!res.ok) throw new Error('Retryable failure'); // Will retry
  return res.json();
});

// Catching Errors
try { await step.do('risky op', async () => { throw new NonRetryableError('Failed'); }); } catch (e) { await step.do('cleanup', async () => {}); }

// Idempotency
await step.do('charge', async () => {
  const sub = await fetch(`https://api/subscriptions/${id}`).then(r => r.json());
  if (sub.charged) return sub; // Already done
  return await fetch(`https://api/subscriptions/${id}`, {method: 'POST', body: JSON.stringify({ amount: 10.0 })}).then(r => r.json());
});
```

## Type Constraints

Params and step returns must be `Rpc.Serializable<T>`:

```typescript
// ✅ Valid types
type ValidParams = {
  userId: string;
  count: number;
  tags: string[];
  metadata: Record<string, unknown>;
};

// ❌ Invalid types
type InvalidParams = {
  callback: () => void;      // Functions not serializable
  symbol: symbol;            // Symbols not serializable
  circular: any;             // Circular references not allowed
};

// Step returns follow same rules
const result = await step.do('fetch', async () => {
  return { userId: '123', data: [1, 2, 3] }; // ✅ Plain object
});
```

## Sleep & Scheduling

```typescript
// Relative
await step.sleep('wait 1 hour', '1 hour');
await step.sleep('wait 30 days', '30 days');
await step.sleep('wait 5s', 5000); // ms

// Absolute
await step.sleepUntil('launch date', Date.parse('24 Oct 2024 13:00:00 UTC'));
await step.sleepUntil('deadline', new Date('2024-12-31T23:59:59Z'));
```

Units: second, minute, hour, day, week, month, year. Max: 365 days.
Sleeping instances don't count toward concurrency.

## Parameters

**Pass from Worker:**
```typescript
const instance = await env.MY_WORKFLOW.create({
  id: crypto.randomUUID(),
  params: { userId: 'user123', email: 'user@example.com' }
});
```

**Access in Workflow:**
```typescript
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
  const userId = event.params.userId;
  const instanceId = event.instanceId;
  const createdAt = event.timestamp;
}
```

**CLI Trigger:**
```bash
npx wrangler workflows trigger my-workflow '{"userId":"user123"}'
```

## Wrangler CLI

```bash
npm create cloudflare@latest my-workflow -- --template "cloudflare/workflows-starter"
npx wrangler deploy
npx wrangler workflows list
npx wrangler workflows trigger my-workflow '{"userId":"user123"}'
npx wrangler workflows instances list my-workflow
npx wrangler workflows instances describe my-workflow instance-id
npx wrangler workflows instances pause/resume/terminate my-workflow instance-id
```

## REST API

```bash
# Create
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances" -H "Authorization: Bearer {token}" -d '{"id":"custom-id","params":{"userId":"user123"}}'

# Status
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/status" -H "Authorization: Bearer {token}"

# Send Event
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/events" -H "Authorization: Bearer {token}" -d '{"type":"approval","payload":{"approved":true}}'
```

See: [configuration.md](./configuration.md), [patterns.md](./patterns.md)

Files in this skill

  • README.md1.1 KB
  • skill.md6.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.