{
  "schemaVersion": "1.0",
  "item": {
    "slug": "unione",
    "name": "UniOne Email API",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/selzy-openclaw/unione",
    "canonicalUrl": "https://clawhub.ai/selzy-openclaw/unione",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/unione",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=unione",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/unione"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/unione",
    "agentPageUrl": "https://openagent3.xyz/skills/unione/agent",
    "manifestUrl": "https://openagent3.xyz/skills/unione/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/unione/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "UniOne Email API",
        "body": "UniOne is a transactional email service with Web API for sending transactional and marketing emails at scale (up to 3,000 emails/sec). This skill lets you send emails, manage templates, validate addresses, track delivery, and more."
      },
      {
        "title": "Authentication",
        "body": "All requests require the UNIONE_API_KEY environment variable. Pass it as the X-API-KEY header.\n\nBase URL: https://api.unione.io/en/transactional/api/v1/{method}.json?platform=openclaw\n\nAll methods use POST with JSON body."
      },
      {
        "title": "CRITICAL: Domain Setup (Required Before Sending)",
        "body": "Emails will not be delivered until the sender's domain is verified. Before attempting to send any email, ensure the domain is set up:"
      },
      {
        "title": "Step 1: Get DNS Record Values — domain/get-dns-records.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/get-dns-records.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'\n\nAPI response returns raw values (not ready-to-paste DNS records):\n\n{\n  \"status\": \"success\",\n  \"domain\": \"yourdomain.com\",\n  \"verification-record\": \"unione-validate-hash=483bb362ebdbeedd755cfb1d4d661\",\n  \"dkim\": \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo7\"\n}\n\nThe user must create 3 DNS TXT records from these values:\n\nRecord HostRecord TypeValue@TXTunione-validate-hash=<verification-record from response>us._domainkeyTXTk=rsa; p=<dkim from response>@TXTv=spf1 include:spf.unione.io ~all\n\nPresent these 3 records clearly to the user and instruct them to add them at their DNS provider (Cloudflare, Route53, GoDaddy, etc.). The SPF record is always the same — it is not returned by the API."
      },
      {
        "title": "Step 2: Verify Domain Ownership — domain/validate-verification.json",
        "body": "After the user has added DNS records:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/validate-verification.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'"
      },
      {
        "title": "Step 3: Validate DKIM — domain/validate-dkim.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/validate-dkim.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'"
      },
      {
        "title": "Step 4: List All Domains — domain/list.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{}'\n\nIf domain verification fails: DNS propagation can take up to 48 hours. Suggest the user waits and retries, or checks their DNS records for typos."
      },
      {
        "title": "Retry Logic",
        "body": "When making API requests, implement exponential backoff for retryable errors:\n\nRetryable errors (DO retry with exponential backoff):\n\nHTTP CodeMeaningRetry Strategy429Rate limitedWait, then retry. Respect Retry-After header if present500Internal server errorRetry up to 3 times502Bad gatewayRetry up to 3 times503Service unavailableRetry up to 3 times504Gateway timeoutRetry up to 3 times\n\nRecommended retry schedule:\n\nAttemptDelay1Immediate21 second35 seconds430 seconds\n\nNon-retryable errors (do NOT retry):\n\nHTTP CodeMeaningAction400Bad requestFix the request parameters401UnauthorizedCheck API key403ForbiddenCheck permissions / domain verification404Endpoint not foundCheck the method path413Payload too largeReduce request size"
      },
      {
        "title": "Idempotency",
        "body": "For email/send.json, always include an idempotency_key to prevent duplicate sends during retries. This is critical for production systems.\n\nThe idempotency_key is a unique string (UUID recommended) passed in the request body. If UniOne receives two requests with the same key, the second request returns the result of the first without sending another email.\n\nAlways generate a unique idempotency key per logical send operation, and reuse the same key when retrying the same send."
      },
      {
        "title": "1. Send Email — email/send.json",
        "body": "Send a transactional or marketing email to one or more recipients. Supports personalization via substitutions, templates, attachments, tracking, and metadata."
      },
      {
        "title": "curl",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\n          \"email\": \"recipient@example.com\",\n          \"substitutions\": {\n            \"to_name\": \"John Smith\"\n          }\n        }\n      ],\n      \"body\": {\n        \"html\": \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n        \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\"\n      },\n      \"subject\": \"Order Confirmation\",\n      \"from_email\": \"noreply@yourdomain.com\",\n      \"from_name\": \"Your Store\"\n    }\n  }'"
      },
      {
        "title": "Node.js",
        "body": "const response = await fetch(\"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\", {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-API-KEY\": process.env.UNIONE_API_KEY\n  },\n  body: JSON.stringify({\n    idempotency_key: crypto.randomUUID(),\n    message: {\n      recipients: [{ email: \"recipient@example.com\", substitutions: { to_name: \"John\" } }],\n      body: {\n        html: \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n        plaintext: \"Hello, {{to_name}}! Your order has been confirmed.\"\n      },\n      subject: \"Order Confirmation\",\n      from_email: \"noreply@yourdomain.com\",\n      from_name: \"Your Store\"\n    }\n  })\n});\nconst data = await response.json();\n// data.status === \"success\" → data.job_id, data.emails"
      },
      {
        "title": "Python",
        "body": "import requests, uuid, os\n\nresponse = requests.post(\n    \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\",\n    headers={\n        \"Content-Type\": \"application/json\",\n        \"X-API-KEY\": os.environ[\"UNIONE_API_KEY\"]\n    },\n    json={\n        \"idempotency_key\": str(uuid.uuid4()),\n        \"message\": {\n            \"recipients\": [{\"email\": \"recipient@example.com\", \"substitutions\": {\"to_name\": \"John\"}}],\n            \"body\": {\n                \"html\": \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\"\n            },\n            \"subject\": \"Order Confirmation\",\n            \"from_email\": \"noreply@yourdomain.com\",\n            \"from_name\": \"Your Store\"\n        }\n    }\n)\ndata = response.json()  # data[\"status\"] == \"success\" → data[\"job_id\"], data[\"emails\"]"
      },
      {
        "title": "Go",
        "body": "package main\n\nimport (\n    \"bytes\"\n    \"encoding/json\"\n    \"fmt\"\n    \"net/http\"\n    \"os\"\n    \"github.com/google/uuid\"\n)\n\nfunc sendEmail() error {\n    payload := map[string]interface{}{\n        \"idempotency_key\": uuid.New().String(),\n        \"message\": map[string]interface{}{\n            \"recipients\": []map[string]interface{}{\n                {\"email\": \"recipient@example.com\", \"substitutions\": map[string]string{\"to_name\": \"John\"}},\n            },\n            \"body\": map[string]string{\n                \"html\":      \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\",\n            },\n            \"subject\":    \"Order Confirmation\",\n            \"from_email\": \"noreply@yourdomain.com\",\n            \"from_name\":  \"Your Store\",\n        },\n    }\n    body, _ := json.Marshal(payload)\n    req, _ := http.NewRequest(\"POST\",\n        \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\",\n        bytes.NewReader(body))\n    req.Header.Set(\"Content-Type\", \"application/json\")\n    req.Header.Set(\"X-API-KEY\", os.Getenv(\"UNIONE_API_KEY\"))\n    resp, err := http.DefaultClient.Do(req)\n    if err != nil {\n        return err\n    }\n    defer resp.Body.Close()\n    var result map[string]interface{}\n    json.NewDecoder(resp.Body).Decode(&result)\n    fmt.Println(result) // result[\"status\"] == \"success\"\n    return nil\n}"
      },
      {
        "title": "PHP",
        "body": "$ch = curl_init(\"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\");\ncurl_setopt_array($ch, [\n    CURLOPT_POST => true,\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        \"Content-Type: application/json\",\n        \"X-API-KEY: \" . getenv(\"UNIONE_API_KEY\")\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"idempotency_key\" => bin2hex(random_bytes(16)),\n        \"message\" => [\n            \"recipients\" => [[\"email\" => \"recipient@example.com\", \"substitutions\" => [\"to_name\" => \"John\"]]],\n            \"body\" => [\n                \"html\" => \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\" => \"Hello, {{to_name}}! Your order has been confirmed.\"\n            ],\n            \"subject\" => \"Order Confirmation\",\n            \"from_email\" => \"noreply@yourdomain.com\",\n            \"from_name\" => \"Your Store\"\n        ]\n    ])\n]);\n$response = curl_exec($ch);\n$data = json_decode($response, true); // $data[\"status\"] === \"success\"\n\nSuccess response:\n\n{\n  \"status\": \"success\",\n  \"job_id\": \"1ZymBc-00041N-9X\",\n  \"emails\": [\"recipient@example.com\"]\n}\n\nFull parameters for message object:\n\nParameterTypeRequiredDescriptionrecipientsarrayYesArray of recipient objects. Each has email (required), substitutions (object), metadata (object)body.htmlstringYes*HTML content. Use {{variable}} for substitutionsbody.plaintextstringNoPlain text versionsubjectstringYes*Email subject line. Supports {{substitutions}}from_emailstringYes*Sender email (must be from a verified domain)from_namestringNoSender display namereply_tostringNoReply-to email addresstemplate_idstringNoUse a stored template instead of body/subjecttagsarrayNoTags for categorizing and filteringtrack_links0/1NoEnable click tracking (default: 0)track_read0/1NoEnable open tracking (default: 0)global_languagestringNoLanguage for unsubscribe footer: en, de, fr, es, it, pl, pt, ru, ua, betemplate_enginestringNo\"simple\" (default) or \"velocity\" or \"liquid\"global_substitutionsobjectNoVariables available to all recipientsattachmentsarrayNoArray of {type, name, content} where content is base64skip_unsubscribe0/1NoSkip unsubscribe footer (use 1 only for transactional)headersobjectNoCustom email headers\n\n*Not required if template_id is used.\n\nTop-level parameter:\n\nParameterTypeRequiredDescriptionidempotency_keystringRecommendedUnique key (UUID) to prevent duplicate sends on retry. Max 36 chars.\n\nSend with template:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\n          \"email\": \"customer@example.com\",\n          \"substitutions\": {\n            \"to_name\": \"Alice\",\n            \"order_id\": \"ORD-12345\",\n            \"total\": \"$59.99\"\n          }\n        }\n      ],\n      \"template_id\": \"your-template-id\",\n      \"from_email\": \"shop@yourdomain.com\",\n      \"from_name\": \"My Shop\"\n    }\n  }'\n\nSend to multiple recipients with personalization:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\"email\": \"alice@example.com\", \"substitutions\": {\"to_name\": \"Alice\"}},\n        {\"email\": \"bob@example.com\", \"substitutions\": {\"to_name\": \"Bob\"}}\n      ],\n      \"body\": {\n        \"html\": \"<p>Hi {{to_name}}, check out our new {{promo_name}}!</p>\"\n      },\n      \"subject\": \"Special offer for you, {{to_name}}!\",\n      \"from_email\": \"marketing@yourdomain.com\",\n      \"from_name\": \"Marketing Team\",\n      \"global_substitutions\": {\"promo_name\": \"Summer Sale\"},\n      \"track_links\": 1,\n      \"track_read\": 1,\n      \"tags\": [\"promo\", \"summer-2026\"]\n    }\n  }'"
      },
      {
        "title": "2. Email Validation — email-validation/single.json",
        "body": "Validate an email address to check if it exists and is deliverable.\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email-validation/single.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"email\": \"user@example.com\"}'\n\nResponse:\n\n{\n  \"status\": \"success\",\n  \"email\": \"user@example.com\",\n  \"result\": \"valid\",\n  \"local_part\": \"user\",\n  \"domain\": \"example.com\",\n  \"mx_found\": true,\n  \"mx_record\": \"mail.example.com\"\n}\n\nPossible result values: \"valid\", \"invalid\", \"unresolvable\", \"unknown\"."
      },
      {
        "title": "3.1 Create/Update Template — template/set.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/template/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"template\": {\n      \"name\": \"Order Confirmation\",\n      \"subject\": \"Your order {{order_id}} is confirmed\",\n      \"template_engine\": \"simple\",\n      \"body\": {\n        \"html\": \"<h1>Thank you, {{to_name}}!</h1><p>Order {{order_id}} total: {{total}}</p>\",\n        \"plaintext\": \"Thank you, {{to_name}}! Order {{order_id}} total: {{total}}\"\n      },\n      \"from_email\": \"shop@yourdomain.com\",\n      \"from_name\": \"My Shop\"\n    }\n  }'\n\nResponse: {\"status\": \"success\", \"template\": {\"id\": \"generated-template-id\"}}\n\nTo update an existing template, include the \"id\" field in the template object."
      },
      {
        "title": "3.2 Get Template — template/get.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/template/get.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"id\": \"template-id-here\"}'"
      },
      {
        "title": "3.3 List Templates — template/list.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/template/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"limit\": 50, \"offset\": 0}'"
      },
      {
        "title": "3.4 Delete Template — template/delete.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/template/delete.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"id\": \"template-id-here\"}'"
      },
      {
        "title": "4. Webhook Management",
        "body": "Webhooks send real-time notifications about email events to your URL."
      },
      {
        "title": "4.1 Set Webhook — webhook/set.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/webhook/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"url\": \"https://yourapp.com/unione-webhook\",\n    \"events\": {\n      \"email_status\": [\n        \"delivered\", \"opened\", \"clicked\", \"unsubscribed\",\n        \"soft_bounced\", \"hard_bounced\", \"spam\"\n      ]\n    }\n  }'"
      },
      {
        "title": "4.2 List Webhooks — webhook/list.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/webhook/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{}'"
      },
      {
        "title": "4.3 Get / Delete Webhook — webhook/get.json / webhook/delete.json",
        "body": "# Get\ncurl -X POST \".../webhook/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"url\": \"https://yourapp.com/unione-webhook\"}'\n\n# Delete\ncurl -X POST \".../webhook/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"url\": \"https://yourapp.com/unione-webhook\"}'"
      },
      {
        "title": "5.1 Add — suppression/set.json",
        "body": "curl -X POST \"https://api.unione.io/en/transactional/api/v1/suppression/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"email\": \"user@example.com\", \"cause\": \"unsubscribed\", \"created\": \"2026-01-15 12:00:00\"}'\n\nCause values: \"unsubscribed\", \"temporary_unavailable\", \"permanent_unavailable\", \"complained\"."
      },
      {
        "title": "5.2 Check — suppression/get.json",
        "body": "curl -X POST \".../suppression/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"email\": \"user@example.com\"}'"
      },
      {
        "title": "5.3 List — suppression/list.json",
        "body": "curl -X POST \".../suppression/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"cause\": \"hard_bounced\", \"limit\": 50, \"offset\": 0}'"
      },
      {
        "title": "5.4 Delete — suppression/delete.json",
        "body": "curl -X POST \".../suppression/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"email\": \"user@example.com\"}'"
      },
      {
        "title": "6.1 Create — event-dump/create.json",
        "body": "curl -X POST \".../event-dump/create.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"start_time\": \"2026-01-01 00:00:00\", \"end_time\": \"2026-01-31 23:59:59\", \"limit\": 50000, \"all_events\": true}'"
      },
      {
        "title": "6.2 Get / List / Delete",
        "body": "# Get dump status and download URL\ncurl -X POST \".../event-dump/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"dump_id\": \"dump-id\"}'\n\n# List all dumps\ncurl -X POST \".../event-dump/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n# Delete a dump\ncurl -X POST \".../event-dump/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"dump_id\": \"dump-id\"}'"
      },
      {
        "title": "7. Tags — tag/list.json / tag/delete.json",
        "body": "# List tags\ncurl -X POST \".../tag/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n# Delete tag\ncurl -X POST \".../tag/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"tag_id\": 123}'"
      },
      {
        "title": "8. Projects — project/create.json / project/list.json",
        "body": "# Create project\ncurl -X POST \".../project/create.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"project\": {\"name\": \"My Project\", \"send_enabled\": true}}'\n\n# List projects\ncurl -X POST \".../project/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'"
      },
      {
        "title": "9. System Info — system/info.json",
        "body": "curl -X POST \".../system/info.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'"
      },
      {
        "title": "10. Subscribe (Double Opt-In) — email/subscribe.json",
        "body": "curl -X POST \".../email/subscribe.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"from_email\": \"newsletter@yourdomain.com\", \"from_name\": \"Newsletter\", \"to_email\": \"newsubscriber@example.com\"}'"
      },
      {
        "title": "Instructions for the Agent",
        "body": "Domain setup is mandatory. Before the first send, always check if the user's domain is verified. Run domain/list.json to check. If not verified, guide them through the domain setup process (Section: Domain Setup).\nAlways use api.unione.io as the API host for all requests.\nNever send an email without explicit user confirmation. Always show the recipient, subject, and body summary before executing email/send.json.\nAlways include idempotency_key in email/send.json requests. Generate a UUID for each unique send. Reuse the same key when retrying.\nImplement retry logic for 429 and 5xx errors with exponential backoff (see Error Handling section). Never retry 400, 401, 403, 404, 413 errors.\nFor template operations, list available templates first before asking which one to use.\nFor validation, report the result clearly and suggest action.\nHandle errors gracefully. If a request returns an error, explain what went wrong and suggest a fix.\nRemind users that the from_email domain must be verified in their UniOne account.\nSubstitution syntax uses double curly braces: {{variable_name}}.\nAttachments must be base64-encoded. Help the user encode files if needed.\nSecurity: Never log or display the full API key. Remind users to keep their API key secret.\nCode language: When the user's project uses a specific language (Node.js, Python, Go, PHP, etc.), provide code examples in that language. The examples in this skill can be adapted to any language that can make HTTP POST requests with JSON."
      },
      {
        "title": "\"Send a test email\"",
        "body": "Check domain verification (domain/list.json)\nIf domain not verified, guide through domain setup\nAsk for recipient email address\nCompose a simple test message\nConfirm with user before sending\nExecute email/send.json with idempotency_key\nReport the job_id on success"
      },
      {
        "title": "\"Check my deliverability setup\"",
        "body": "Run system/info.json to get account status\nRun domain/list.json to check domain verification\nFor each unverified domain, run domain/get-dns-records.json and show required records\nRun domain/validate-dkim.json to check DKIM\nSuggest fixes if domains are not fully verified"
      },
      {
        "title": "\"Validate a list of emails\"",
        "body": "For each email, call email-validation/single.json\nCategorize results: valid, invalid, unknown\nReport summary"
      },
      {
        "title": "\"Set up delivery tracking\"",
        "body": "Ask for webhook URL and events to track\nExecute webhook/set.json\nConfirm setup"
      },
      {
        "title": "Resources",
        "body": "Full API Reference: https://docs.unione.io/en/web-api-ref\nGetting Started: https://docs.unione.io/en/\nTemplate Engines: https://docs.unione.io/en/web-api#section-template-engines\nSign Up: https://cp.unione.io/en/user/registration/"
      }
    ],
    "body": "UniOne Email API\n\nUniOne is a transactional email service with Web API for sending transactional and marketing emails at scale (up to 3,000 emails/sec). This skill lets you send emails, manage templates, validate addresses, track delivery, and more.\n\nAuthentication\n\nAll requests require the UNIONE_API_KEY environment variable. Pass it as the X-API-KEY header.\n\nBase URL: https://api.unione.io/en/transactional/api/v1/{method}.json?platform=openclaw\n\nAll methods use POST with JSON body.\n\nCRITICAL: Domain Setup (Required Before Sending)\n\nEmails will not be delivered until the sender's domain is verified. Before attempting to send any email, ensure the domain is set up:\n\nStep 1: Get DNS Record Values — domain/get-dns-records.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/get-dns-records.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'\n\n\nAPI response returns raw values (not ready-to-paste DNS records):\n\n{\n  \"status\": \"success\",\n  \"domain\": \"yourdomain.com\",\n  \"verification-record\": \"unione-validate-hash=483bb362ebdbeedd755cfb1d4d661\",\n  \"dkim\": \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo7\"\n}\n\n\nThe user must create 3 DNS TXT records from these values:\n\nRecord Host\tRecord Type\tValue\n@\tTXT\tunione-validate-hash=<verification-record from response>\nus._domainkey\tTXT\tk=rsa; p=<dkim from response>\n@\tTXT\tv=spf1 include:spf.unione.io ~all\n\nPresent these 3 records clearly to the user and instruct them to add them at their DNS provider (Cloudflare, Route53, GoDaddy, etc.). The SPF record is always the same — it is not returned by the API.\n\nStep 2: Verify Domain Ownership — domain/validate-verification.json\n\nAfter the user has added DNS records:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/validate-verification.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'\n\nStep 3: Validate DKIM — domain/validate-dkim.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/validate-dkim.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"domain\": \"yourdomain.com\"}'\n\nStep 4: List All Domains — domain/list.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/domain/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{}'\n\n\nIf domain verification fails: DNS propagation can take up to 48 hours. Suggest the user waits and retries, or checks their DNS records for typos.\n\nError Handling & Retry Policy\nRetry Logic\n\nWhen making API requests, implement exponential backoff for retryable errors:\n\nRetryable errors (DO retry with exponential backoff):\n\nHTTP Code\tMeaning\tRetry Strategy\n429\tRate limited\tWait, then retry. Respect Retry-After header if present\n500\tInternal server error\tRetry up to 3 times\n502\tBad gateway\tRetry up to 3 times\n503\tService unavailable\tRetry up to 3 times\n504\tGateway timeout\tRetry up to 3 times\n\nRecommended retry schedule:\n\nAttempt\tDelay\n1\tImmediate\n2\t1 second\n3\t5 seconds\n4\t30 seconds\n\nNon-retryable errors (do NOT retry):\n\nHTTP Code\tMeaning\tAction\n400\tBad request\tFix the request parameters\n401\tUnauthorized\tCheck API key\n403\tForbidden\tCheck permissions / domain verification\n404\tEndpoint not found\tCheck the method path\n413\tPayload too large\tReduce request size\nIdempotency\n\nFor email/send.json, always include an idempotency_key to prevent duplicate sends during retries. This is critical for production systems.\n\nThe idempotency_key is a unique string (UUID recommended) passed in the request body. If UniOne receives two requests with the same key, the second request returns the result of the first without sending another email.\n\nAlways generate a unique idempotency key per logical send operation, and reuse the same key when retrying the same send.\n\n1. Send Email — email/send.json\n\nSend a transactional or marketing email to one or more recipients. Supports personalization via substitutions, templates, attachments, tracking, and metadata.\n\ncurl\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\n          \"email\": \"recipient@example.com\",\n          \"substitutions\": {\n            \"to_name\": \"John Smith\"\n          }\n        }\n      ],\n      \"body\": {\n        \"html\": \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n        \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\"\n      },\n      \"subject\": \"Order Confirmation\",\n      \"from_email\": \"noreply@yourdomain.com\",\n      \"from_name\": \"Your Store\"\n    }\n  }'\n\nNode.js\nconst response = await fetch(\"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\", {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-API-KEY\": process.env.UNIONE_API_KEY\n  },\n  body: JSON.stringify({\n    idempotency_key: crypto.randomUUID(),\n    message: {\n      recipients: [{ email: \"recipient@example.com\", substitutions: { to_name: \"John\" } }],\n      body: {\n        html: \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n        plaintext: \"Hello, {{to_name}}! Your order has been confirmed.\"\n      },\n      subject: \"Order Confirmation\",\n      from_email: \"noreply@yourdomain.com\",\n      from_name: \"Your Store\"\n    }\n  })\n});\nconst data = await response.json();\n// data.status === \"success\" → data.job_id, data.emails\n\nPython\nimport requests, uuid, os\n\nresponse = requests.post(\n    \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\",\n    headers={\n        \"Content-Type\": \"application/json\",\n        \"X-API-KEY\": os.environ[\"UNIONE_API_KEY\"]\n    },\n    json={\n        \"idempotency_key\": str(uuid.uuid4()),\n        \"message\": {\n            \"recipients\": [{\"email\": \"recipient@example.com\", \"substitutions\": {\"to_name\": \"John\"}}],\n            \"body\": {\n                \"html\": \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\"\n            },\n            \"subject\": \"Order Confirmation\",\n            \"from_email\": \"noreply@yourdomain.com\",\n            \"from_name\": \"Your Store\"\n        }\n    }\n)\ndata = response.json()  # data[\"status\"] == \"success\" → data[\"job_id\"], data[\"emails\"]\n\nGo\npackage main\n\nimport (\n    \"bytes\"\n    \"encoding/json\"\n    \"fmt\"\n    \"net/http\"\n    \"os\"\n    \"github.com/google/uuid\"\n)\n\nfunc sendEmail() error {\n    payload := map[string]interface{}{\n        \"idempotency_key\": uuid.New().String(),\n        \"message\": map[string]interface{}{\n            \"recipients\": []map[string]interface{}{\n                {\"email\": \"recipient@example.com\", \"substitutions\": map[string]string{\"to_name\": \"John\"}},\n            },\n            \"body\": map[string]string{\n                \"html\":      \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\": \"Hello, {{to_name}}! Your order has been confirmed.\",\n            },\n            \"subject\":    \"Order Confirmation\",\n            \"from_email\": \"noreply@yourdomain.com\",\n            \"from_name\":  \"Your Store\",\n        },\n    }\n    body, _ := json.Marshal(payload)\n    req, _ := http.NewRequest(\"POST\",\n        \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\",\n        bytes.NewReader(body))\n    req.Header.Set(\"Content-Type\", \"application/json\")\n    req.Header.Set(\"X-API-KEY\", os.Getenv(\"UNIONE_API_KEY\"))\n    resp, err := http.DefaultClient.Do(req)\n    if err != nil {\n        return err\n    }\n    defer resp.Body.Close()\n    var result map[string]interface{}\n    json.NewDecoder(resp.Body).Decode(&result)\n    fmt.Println(result) // result[\"status\"] == \"success\"\n    return nil\n}\n\nPHP\n$ch = curl_init(\"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\");\ncurl_setopt_array($ch, [\n    CURLOPT_POST => true,\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        \"Content-Type: application/json\",\n        \"X-API-KEY: \" . getenv(\"UNIONE_API_KEY\")\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"idempotency_key\" => bin2hex(random_bytes(16)),\n        \"message\" => [\n            \"recipients\" => [[\"email\" => \"recipient@example.com\", \"substitutions\" => [\"to_name\" => \"John\"]]],\n            \"body\" => [\n                \"html\" => \"<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>\",\n                \"plaintext\" => \"Hello, {{to_name}}! Your order has been confirmed.\"\n            ],\n            \"subject\" => \"Order Confirmation\",\n            \"from_email\" => \"noreply@yourdomain.com\",\n            \"from_name\" => \"Your Store\"\n        ]\n    ])\n]);\n$response = curl_exec($ch);\n$data = json_decode($response, true); // $data[\"status\"] === \"success\"\n\n\nSuccess response:\n\n{\n  \"status\": \"success\",\n  \"job_id\": \"1ZymBc-00041N-9X\",\n  \"emails\": [\"recipient@example.com\"]\n}\n\n\nFull parameters for message object:\n\nParameter\tType\tRequired\tDescription\nrecipients\tarray\tYes\tArray of recipient objects. Each has email (required), substitutions (object), metadata (object)\nbody.html\tstring\tYes*\tHTML content. Use {{variable}} for substitutions\nbody.plaintext\tstring\tNo\tPlain text version\nsubject\tstring\tYes*\tEmail subject line. Supports {{substitutions}}\nfrom_email\tstring\tYes*\tSender email (must be from a verified domain)\nfrom_name\tstring\tNo\tSender display name\nreply_to\tstring\tNo\tReply-to email address\ntemplate_id\tstring\tNo\tUse a stored template instead of body/subject\ntags\tarray\tNo\tTags for categorizing and filtering\ntrack_links\t0/1\tNo\tEnable click tracking (default: 0)\ntrack_read\t0/1\tNo\tEnable open tracking (default: 0)\nglobal_language\tstring\tNo\tLanguage for unsubscribe footer: en, de, fr, es, it, pl, pt, ru, ua, be\ntemplate_engine\tstring\tNo\t\"simple\" (default) or \"velocity\" or \"liquid\"\nglobal_substitutions\tobject\tNo\tVariables available to all recipients\nattachments\tarray\tNo\tArray of {type, name, content} where content is base64\nskip_unsubscribe\t0/1\tNo\tSkip unsubscribe footer (use 1 only for transactional)\nheaders\tobject\tNo\tCustom email headers\n\n*Not required if template_id is used.\n\nTop-level parameter:\n\nParameter\tType\tRequired\tDescription\nidempotency_key\tstring\tRecommended\tUnique key (UUID) to prevent duplicate sends on retry. Max 36 chars.\n\nSend with template:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\n          \"email\": \"customer@example.com\",\n          \"substitutions\": {\n            \"to_name\": \"Alice\",\n            \"order_id\": \"ORD-12345\",\n            \"total\": \"$59.99\"\n          }\n        }\n      ],\n      \"template_id\": \"your-template-id\",\n      \"from_email\": \"shop@yourdomain.com\",\n      \"from_name\": \"My Shop\"\n    }\n  }'\n\n\nSend to multiple recipients with personalization:\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"idempotency_key\": \"unique-uuid-here\",\n    \"message\": {\n      \"recipients\": [\n        {\"email\": \"alice@example.com\", \"substitutions\": {\"to_name\": \"Alice\"}},\n        {\"email\": \"bob@example.com\", \"substitutions\": {\"to_name\": \"Bob\"}}\n      ],\n      \"body\": {\n        \"html\": \"<p>Hi {{to_name}}, check out our new {{promo_name}}!</p>\"\n      },\n      \"subject\": \"Special offer for you, {{to_name}}!\",\n      \"from_email\": \"marketing@yourdomain.com\",\n      \"from_name\": \"Marketing Team\",\n      \"global_substitutions\": {\"promo_name\": \"Summer Sale\"},\n      \"track_links\": 1,\n      \"track_read\": 1,\n      \"tags\": [\"promo\", \"summer-2026\"]\n    }\n  }'\n\n2. Email Validation — email-validation/single.json\n\nValidate an email address to check if it exists and is deliverable.\n\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/email-validation/single.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"email\": \"user@example.com\"}'\n\n\nResponse:\n\n{\n  \"status\": \"success\",\n  \"email\": \"user@example.com\",\n  \"result\": \"valid\",\n  \"local_part\": \"user\",\n  \"domain\": \"example.com\",\n  \"mx_found\": true,\n  \"mx_record\": \"mail.example.com\"\n}\n\n\nPossible result values: \"valid\", \"invalid\", \"unresolvable\", \"unknown\".\n\n3. Template Management\n3.1 Create/Update Template — template/set.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/template/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"template\": {\n      \"name\": \"Order Confirmation\",\n      \"subject\": \"Your order {{order_id}} is confirmed\",\n      \"template_engine\": \"simple\",\n      \"body\": {\n        \"html\": \"<h1>Thank you, {{to_name}}!</h1><p>Order {{order_id}} total: {{total}}</p>\",\n        \"plaintext\": \"Thank you, {{to_name}}! Order {{order_id}} total: {{total}}\"\n      },\n      \"from_email\": \"shop@yourdomain.com\",\n      \"from_name\": \"My Shop\"\n    }\n  }'\n\n\nResponse: {\"status\": \"success\", \"template\": {\"id\": \"generated-template-id\"}}\n\nTo update an existing template, include the \"id\" field in the template object.\n\n3.2 Get Template — template/get.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/template/get.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"id\": \"template-id-here\"}'\n\n3.3 List Templates — template/list.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/template/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"limit\": 50, \"offset\": 0}'\n\n3.4 Delete Template — template/delete.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/template/delete.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"id\": \"template-id-here\"}'\n\n4. Webhook Management\n\nWebhooks send real-time notifications about email events to your URL.\n\n4.1 Set Webhook — webhook/set.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/webhook/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\n    \"url\": \"https://yourapp.com/unione-webhook\",\n    \"events\": {\n      \"email_status\": [\n        \"delivered\", \"opened\", \"clicked\", \"unsubscribed\",\n        \"soft_bounced\", \"hard_bounced\", \"spam\"\n      ]\n    }\n  }'\n\n4.2 List Webhooks — webhook/list.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/webhook/list.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{}'\n\n4.3 Get / Delete Webhook — webhook/get.json / webhook/delete.json\n# Get\ncurl -X POST \".../webhook/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"url\": \"https://yourapp.com/unione-webhook\"}'\n\n# Delete\ncurl -X POST \".../webhook/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"url\": \"https://yourapp.com/unione-webhook\"}'\n\n5. Suppression List Management\n5.1 Add — suppression/set.json\ncurl -X POST \"https://api.unione.io/en/transactional/api/v1/suppression/set.json?platform=openclaw\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -d '{\"email\": \"user@example.com\", \"cause\": \"unsubscribed\", \"created\": \"2026-01-15 12:00:00\"}'\n\n\nCause values: \"unsubscribed\", \"temporary_unavailable\", \"permanent_unavailable\", \"complained\".\n\n5.2 Check — suppression/get.json\ncurl -X POST \".../suppression/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"email\": \"user@example.com\"}'\n\n5.3 List — suppression/list.json\ncurl -X POST \".../suppression/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"cause\": \"hard_bounced\", \"limit\": 50, \"offset\": 0}'\n\n5.4 Delete — suppression/delete.json\ncurl -X POST \".../suppression/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"email\": \"user@example.com\"}'\n\n6. Event Dumps\n6.1 Create — event-dump/create.json\ncurl -X POST \".../event-dump/create.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"start_time\": \"2026-01-01 00:00:00\", \"end_time\": \"2026-01-31 23:59:59\", \"limit\": 50000, \"all_events\": true}'\n\n6.2 Get / List / Delete\n# Get dump status and download URL\ncurl -X POST \".../event-dump/get.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"dump_id\": \"dump-id\"}'\n\n# List all dumps\ncurl -X POST \".../event-dump/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n# Delete a dump\ncurl -X POST \".../event-dump/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"dump_id\": \"dump-id\"}'\n\n7. Tags — tag/list.json / tag/delete.json\n# List tags\ncurl -X POST \".../tag/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n# Delete tag\ncurl -X POST \".../tag/delete.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{\"tag_id\": 123}'\n\n8. Projects — project/create.json / project/list.json\n# Create project\ncurl -X POST \".../project/create.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"project\": {\"name\": \"My Project\", \"send_enabled\": true}}'\n\n# List projects\ncurl -X POST \".../project/list.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n9. System Info — system/info.json\ncurl -X POST \".../system/info.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n\n10. Subscribe (Double Opt-In) — email/subscribe.json\ncurl -X POST \".../email/subscribe.json?platform=openclaw\" -H \"X-API-KEY: $UNIONE_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"from_email\": \"newsletter@yourdomain.com\", \"from_name\": \"Newsletter\", \"to_email\": \"newsubscriber@example.com\"}'\n\nInstructions for the Agent\nDomain setup is mandatory. Before the first send, always check if the user's domain is verified. Run domain/list.json to check. If not verified, guide them through the domain setup process (Section: Domain Setup).\nAlways use api.unione.io as the API host for all requests.\nNever send an email without explicit user confirmation. Always show the recipient, subject, and body summary before executing email/send.json.\nAlways include idempotency_key in email/send.json requests. Generate a UUID for each unique send. Reuse the same key when retrying.\nImplement retry logic for 429 and 5xx errors with exponential backoff (see Error Handling section). Never retry 400, 401, 403, 404, 413 errors.\nFor template operations, list available templates first before asking which one to use.\nFor validation, report the result clearly and suggest action.\nHandle errors gracefully. If a request returns an error, explain what went wrong and suggest a fix.\nRemind users that the from_email domain must be verified in their UniOne account.\nSubstitution syntax uses double curly braces: {{variable_name}}.\nAttachments must be base64-encoded. Help the user encode files if needed.\nSecurity: Never log or display the full API key. Remind users to keep their API key secret.\nCode language: When the user's project uses a specific language (Node.js, Python, Go, PHP, etc.), provide code examples in that language. The examples in this skill can be adapted to any language that can make HTTP POST requests with JSON.\nCommon Workflows\n\"Send a test email\"\nCheck domain verification (domain/list.json)\nIf domain not verified, guide through domain setup\nAsk for recipient email address\nCompose a simple test message\nConfirm with user before sending\nExecute email/send.json with idempotency_key\nReport the job_id on success\n\"Check my deliverability setup\"\nRun system/info.json to get account status\nRun domain/list.json to check domain verification\nFor each unverified domain, run domain/get-dns-records.json and show required records\nRun domain/validate-dkim.json to check DKIM\nSuggest fixes if domains are not fully verified\n\"Validate a list of emails\"\nFor each email, call email-validation/single.json\nCategorize results: valid, invalid, unknown\nReport summary\n\"Set up delivery tracking\"\nAsk for webhook URL and events to track\nExecute webhook/set.json\nConfirm setup\nResources\nFull API Reference: https://docs.unione.io/en/web-api-ref\nGetting Started: https://docs.unione.io/en/\nTemplate Engines: https://docs.unione.io/en/web-api#section-template-engines\nSign Up: https://cp.unione.io/en/user/registration/"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/selzy-openclaw/unione",
    "publisherUrl": "https://clawhub.ai/selzy-openclaw/unione",
    "owner": "selzy-openclaw",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/unione",
    "downloadUrl": "https://openagent3.xyz/downloads/unione",
    "agentUrl": "https://openagent3.xyz/skills/unione/agent",
    "manifestUrl": "https://openagent3.xyz/skills/unione/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/unione/agent.md"
  }
}