.do

Quick Start Guide

Build your first service in 5 minutes

Build and deploy your first service in just 5 minutes.

Prerequisites

Before you begin, make sure you have:

# Install the .do SDK
npm install sdk.do

# Or with pnpm
pnpm add sdk.do

Requirements:

  • Node.js 18+ or Bun 1.0+
  • A .do account (sign up at platform.do)
  • API key from your dashboard

Your First Service

Let's create a simple content generation service that turns topics into tweet threads.

Set Up Your Environment

Create a new file tweet-service.ts:

import $, { ai, on, send } from 'sdk.do'

// Initialize with your API key
$.configure({
  apiKey: process.env.DO_API_KEY,
})
Make sure you have your API key set in your environment. Get one at platform.do.

Define Your Service

Define what your service does and how it's priced:

const tweetThreadService = await $.Service.create({
  name: 'Tweet Thread Generator',
  description: 'Turn any topic into an engaging Twitter thread',

  // Service type
  type: $.ServiceType.ContentGeneration,

  // What inputs you need
  input: {
    required: ['topic'],
    optional: ['tone', 'length'],
  },

  // Pricing
  pricing: {
    model: 'per-thread',
    rate: 5.0, // $5 per thread
  },
})

Implement the Logic

Add the service execution logic:

on($.ServiceRequest.created, async (request) => {
  // Only handle our service
  if (request.serviceId !== tweetThreadService.id) return

  try {
    // Extract inputs
    const { topic, tone = 'engaging', length = 5 } = request.inputs

    // Generate thread using AI
    const thread = await ai.generate({
      model: 'gpt-5',
      prompt: `Create a ${length}-tweet thread about: ${topic}`,
      context: {
        tone,
        constraints: {
          tweetLength: 280,
          includeHashtags: true,
          includeCallToAction: true,
        },
      },
    })

    // Deliver the result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        thread: thread.tweets,
        hashtags: thread.hashtags,
        estimatedEngagement: thread.metrics.engagement,
      },
    })

    // Charge for the service
    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: tweetThreadService.pricing.rate,
      description: `Tweet Thread: ${topic}`,
    })
  } catch (error) {
    // Handle errors gracefully
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

Test Your Service

Test it with a sample request:

// Create a test request
const testRequest = await send($.ServiceRequest.create, {
  serviceId: tweetThreadService.id,
  customerId: 'test-customer',
  inputs: {
    topic: 'The future of AI in content creation',
    tone: 'professional',
    length: 7,
  },
})

console.log('Service request created:', testRequest.id)

// Listen for results
on($.ServiceResult.delivered, async (result) => {
  if (result.requestId === testRequest.id) {
    console.log('Thread generated:', result.outputs.thread)
    console.log('Hashtags:', result.outputs.hashtags)
  }
})

Deploy

Deploy your service to production:

# Deploy using the CLI
do deploy tweet-service.ts

# Or programmatically
await $.Service.deploy({
  serviceId: tweetThreadService.id,
  environment: 'production',
})

Complete Example

Here's the complete code:

import $, { ai, on, send } from 'sdk.do'

// Configure SDK
$.configure({
  apiKey: process.env.DO_API_KEY,
})

// Define service
const tweetThreadService = await $.Service.create({
  name: 'Tweet Thread Generator',
  description: 'Turn any topic into an engaging Twitter thread',
  type: $.ServiceType.ContentGeneration,

  input: {
    required: ['topic'],
    optional: ['tone', 'length'],
  },

  pricing: {
    model: 'per-thread',
    rate: 5.0,
  },
})

// Implement service logic
on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== tweetThreadService.id) return

  try {
    const { topic, tone = 'engaging', length = 5 } = request.inputs

    const thread = await ai.generate({
      model: 'gpt-5',
      prompt: `Create a ${length}-tweet thread about: ${topic}`,
      context: {
        tone,
        constraints: {
          tweetLength: 280,
          includeHashtags: true,
          includeCallToAction: true,
        },
      },
    })

    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        thread: thread.tweets,
        hashtags: thread.hashtags,
        estimatedEngagement: thread.metrics.engagement,
      },
    })

    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: tweetThreadService.pricing.rate,
      description: `Tweet Thread: ${topic}`,
    })
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

// Start the service
console.log(`Tweet Thread Generator deployed: ${tweetThreadService.id}`)

What You Just Built

Congratulations! You've created a complete service with:

Service definition - Clear inputs, outputs, and pricing ✅ AI integration - Powered by GPT-5 for content generation ✅ Event handling - Responds to requests automatically ✅ Error handling - Graceful failure management ✅ Billing - Automatic payment processing ✅ Production ready - Deployable immediately

Try It Out

Request your service:

# Using the CLI
do request tweet-thread-generator \
  --input topic="AI and the future of work" \
  --input length=10

# Or via API
curl -X POST https://api.do/services/tweet-thread-generator/requests \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "topic": "AI and the future of work",
      "length": 10
    }
  }'

Next Steps

Enhance Your Service

Add more features to your service:

// Add quality checks
const quality = await ai.evaluate({
  content: thread.tweets,
  criteria: {
    engagement: { min: 0.7 },
    clarity: { min: 0.8 },
    sentiment: { target: 'positive' },
  },
})

if (quality.score < 0.8) {
  thread = await ai.improve({
    content: thread.tweets,
    issues: quality.issues,
  })
}

// Add scheduling
await send($.Twitter.scheduleThread, {
  tweets: thread.tweets,
  schedule: request.inputs.publishTime,
  customerId: request.customerId,
})

// Add analytics
await send($.Analytics.track, {
  event: 'thread-generated',
  properties: {
    topic,
    length,
    engagement: thread.metrics.engagement,
  },
})

Learn More Patterns

Explore advanced service patterns:

Explore Service Types

Build different kinds of services:

Master Monetization

Optimize your pricing:

Deploy to Production

Learn deployment best practices:

Common Patterns

Add Authentication

Verify customer access:

on($.ServiceRequest.created, async (request) => {
  // Check subscription
  const subscription = await db.findOne($.Subscription, {
    customerId: request.customerId,
    serviceId: tweetThreadService.id,
    status: 'active',
  })

  if (!subscription) {
    return await send($.ServiceRequest.reject, {
      requestId: request.id,
      reason: 'No active subscription',
    })
  }

  // Check usage limits
  const usage = await getUsageThisMonth(request.customerId)
  if (usage.threads >= subscription.limits.threads) {
    return await send($.ServiceRequest.reject, {
      requestId: request.id,
      reason: 'Monthly limit reached',
      upgrade: { required: true },
    })
  }

  // Continue with service execution...
})

Add Webhooks

Notify customers of results:

on($.ServiceResult.delivered, async (result) => {
  const customer = await db.findOne($.Customer, {
    id: result.customerId,
  })

  if (customer.webhookUrl) {
    await fetch(customer.webhookUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        event: 'service.result.delivered',
        serviceId: result.serviceId,
        requestId: result.requestId,
        outputs: result.outputs,
        timestamp: new Date().toISOString(),
      }),
    })
  }
})

Add Retries

Handle failures gracefully:

on($.ServiceRequest.fail, async (failure) => {
  if (failure.retryable && failure.retryCount < 3) {
    // Wait before retrying
    await sleep(Math.pow(2, failure.retryCount) * 1000)

    // Retry the request
    await send($.ServiceRequest.create, {
      ...failure.originalRequest,
      retryCount: failure.retryCount + 1,
    })
  } else {
    // Final failure - notify customer
    await send($.Customer.notify, {
      customerId: failure.customerId,
      type: 'service-failed',
      message: `Service execution failed: ${failure.error}`,
    })
  }
})

Troubleshooting

Resources

Documentation

Examples

Community

  • Discord - Join the community
  • GitHub - Contribute to the SDK
  • Blog - Latest updates and tutorials
  • Twitter - News and announcements

Get Help

Need assistance? We're here to help:

  • Documentation: Search these docs for answers
  • Community: Ask questions in Discord
  • Support: Email support@do for technical help
  • Enterprise: Contact sales@do for enterprise support

Happy building! 🚀