| name | pinme-email |
| description | Use this skill when a PinMe project (Worker TypeScript) needs to integrate email sending (send_email). Guides AI to generate correct Worker TS code. |
PinMe Worker Email API Integration
Guides how to call PinMe platform's email sending API in a PinMe Worker (TypeScript).
Environment Variables
The following environment variables are automatically injected when the Worker is created — no manual configuration needed:
export interface Env {
DB: D1Database;
API_KEY: string;
BASE_URL?: string;
}
API_KEY is the sole credential for the Worker to call PinMe platform APIs. When BASE_URL is not set, it defaults to https://pinme.cloud.
Send Email API
Endpoint: POST {BASE_URL}/api/v4/send_email
Authentication: X-API-Key header (using env.API_KEY)
Sender: Automatically set to {project_name}@pinme.cloud
Request Format
{
"to": "user@example.com",
"subject": "Your verification code",
"html": "<p>Your code is <strong>123456</strong></p>"
}
| Field | Type | Required | Description |
|---|
to | string | Yes | Recipient email address |
subject | string | Yes | Email subject |
html | string | Yes | HTML body |
Response Format
Success (200):
{ "code": 200, "msg": "ok", "data": { "ok": true } }
Errors:
| HTTP Status | Meaning | data.error Example |
|---|
| 401 | API Key missing or invalid | "X-API-Key header is required" / "Invalid API key" |
| 400 | Parameter validation failed | "Invalid email address" / "Subject is required" |
| 500 | Email service error | "Failed to send email" |
Worker Example Code
async function sendEmail(env: Env, to: string, subject: string, html: string): Promise<{ ok: boolean; error?: string }> {
const baseUrl = env.BASE_URL ?? 'https://pinme.cloud';
const resp = await fetch(`${baseUrl}/api/v4/send_email`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': env.API_KEY,
},
body: JSON.stringify({ to, subject, html }),
});
const result = await resp.json() as { code: number; msg: string; data?: { ok?: boolean; error?: string } };
if (resp.status !== 200 || result.code !== 200) {
return { : , : result.?. || result. || };
}
{ : };
}
(): <> {
{ email } = request.() { : };
code = .().().(, );
result = (env, email, ,
);
(!result.) {
({ : result. }, );
}
({ : });
}
Error Handling Pattern
PinMe platform API unified response format:
interface PinmeResponse<T = unknown> {
code: number;
msg: string;
data?: T;
}
Recommended Unified Error Handler
async function callPinmeAPI<T>(url: string, apiKey: string, body: unknown): Promise<{ data?: T; error?: string }> {
let resp: Response;
try {
resp = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
body: JSON.stringify(body),
});
} catch {
return { error: 'Network error' };
}
if (!resp.ok) {
try {
const err = await resp.json() as PinmeResponse;
return { error: err.data && typeof err.data === 'object' && 'error' in err.data
? (err.data as { error: string }).error
: err. || };
} {
{ : };
}
}
result = resp.() <T>;
(result. !== ) {
{ : result. && result. === && result.
? (result. { : }).
: result. };
}
{ : result. T };
}
Usage Example
const baseUrl = env.BASE_URL ?? 'https://pinme.cloud';
const emailResult = await callPinmeAPI<{ ok: boolean }>(
`${baseUrl}/api/v4/send_email`, env.API_KEY,
{ to: 'user@example.com', subject: 'Hello', html: '<p>Hi</p>' },
);
if (emailResult.error) return json({ error: emailResult.error }, 500);