Skip to main content

Subuser & Domain Management

๐Ÿ‘ฅ Subuser Managementโ€‹

Overviewโ€‹

Each DashClicks account gets its own Sendgrid subuser for reputation isolation. This ensures that one account's email practices don't affect another's sending reputation.

Subuser Architecture Benefits:

  • ๐Ÿ“ง Independent email quotas per account
  • ๐Ÿ“Š Isolated reputation scores
  • ๐Ÿ”’ Separate authentication credentials
  • ๐ŸŒ Individual domain assignments
  • ๐Ÿ“ˆ Per-account analytics

๐Ÿ”— API Endpointsโ€‹

Subuser Operationsโ€‹

EndpointMethodScopeDescription
/v1/integrations/sendgrid/subusersPOSTcommunicationsCreate new subuser
/v1/integrations/sendgrid/subusers/:idPUTcommunicationsEnable/disable subuser
/v1/integrations/sendgrid/subusers/:idDELETEcommunicationsDelete subuser
/v1/integrations/sendgrid/subusers/:id/reputationGETcommunicationsGet subuser reputation score

Domain Operationsโ€‹

EndpointMethodScopeDescription
/v1/integrations/sendgrid/subusers/domainsPOSTaccounts.email_custom_domain, accountsAdd domain to subuser
/v1/integrations/sendgrid/subusers/domains/:domain_idDELETEaccounts.email_custom_domain, accountsDelete subuser domain
/v1/integrations/sendgrid/subusers/domains/:domain_id/validatePOSTaccounts.email_custom_domain, accountsValidate domain DNS

๐Ÿ‘ค Subuser API Referenceโ€‹

Create Subuserโ€‹

Endpoint: POST /v1/integrations/sendgrid/subusers

Purpose: Create new Sendgrid subuser for a DashClicks account

Request Body:

{
"username": "dashclicks_acc_507f191e",
"email": "subuser@dashclicks.com"
}

Validation:

  • username: Required string
  • email: Required email format

Process:

  1. Generate Password: Random 10 characters + "1D" suffix

    const password = Math.random().toString(36).substring(2, 12) + '1D';
  2. Get Available IP: Query Sendgrid for available IP addresses

    GET https://api.sendgrid.com/v3/ips
    Authorization: Bearer {SENDGRID_API_KEY}
  3. Check Existing: Verify subuser doesn't already exist in database

  4. Create Subuser: Call Sendgrid API

    POST https://api.sendgrid.com/v3/subusers
    Authorization: Bearer {SENDGRID_API_KEY}
    Content-Type: application/json

    {
    "username": "dashclicks_acc_507f191e",
    "email": "subuser@dashclicks.com",
    "password": "random12341D",
    "ips": ["192.168.1.1"]
    }
  5. Assign Default Domain: Add default domain to subuser

    PUT https://api.sendgrid.com/v3/whitelabel/domains/{SENDGRID_DEFAULT_DOMAIN_ID}/subuser
    Authorization: Bearer {SENDGRID_API_KEY}

    {
    "username": "dashclicks_acc_507f191e"
    }
  6. Store in Database: Save to account document

    await SubUserCollection.addSubUserDoc({
    account_id: account_id,
    sendgrid: {
    subuser: {
    username: 'dashclicks_acc_507f191e',
    user_id: 123456,
    email: 'subuser@dashclicks.com',
    disabled: false,
    },
    domain_assigned: true,
    domains: [],
    },
    });

Response:

{
"success": true,
"message": "SUCCESS",
"data": {
"username": "dashclicks_acc_507f191e",
"user_id": 123456,
"email": "subuser@dashclicks.com",
"disabled": false
}
}

Error Scenarios:

// Subuser already exists
{
"success": false,
"errno": 400,
"message": "Subuser already exists for this account"
}

// No available IPs
{
"success": false,
"errno": 500,
"message": "No available IP addresses"
}

Update Subuser (Enable/Disable)โ€‹

Endpoint: PUT /v1/integrations/sendgrid/subusers/:id

Purpose: Enable or disable subuser account

Path Parameters:

  • id (required) - DashClicks account ID

Request Body:

{
"disabled": true
}

Sendgrid API:

PATCH https://api.sendgrid.com/v3/subusers/{username}
Authorization: Bearer {SENDGRID_API_KEY}
Content-Type: application/json

{
"disabled": true
}

Database Update:

await SubUserCollection.updateSubUserStatusDoc(account_id, disabled);

Response:

{
"success": true,
"message": "SUCCESS",
"data": {
"username": "dashclicks_acc_507f191e",
"user_id": 123456,
"disabled": true
}
}

Use Cases:

  • Temporarily suspend email sending for an account
  • Re-enable after suspension period
  • Troubleshooting delivery issues

Delete Subuserโ€‹

Endpoint: DELETE /v1/integrations/sendgrid/subusers/:id

Purpose: Permanently delete subuser and all associated data

Path Parameters:

  • id (required) - DashClicks account ID

Process:

  1. Get subuser username from database
  2. Delete via Sendgrid API:
    DELETE https://api.sendgrid.com/v3/subusers/{username}
    Authorization: Bearer {SENDGRID_API_KEY}
  3. Delete from database:
    await SubUserCollection.deleteSubUserDoc(account_id);

Response:

{
"success": true,
"message": "Subuser deleted successfully"
}

Warning: This action is irreversible. All subuser data, including:

  • API keys
  • Domain configurations
  • Email statistics
  • Reputation history

will be permanently deleted.

Get Subuser Reputationโ€‹

Endpoint: GET /v1/integrations/sendgrid/subusers/:id/reputation

Purpose: Retrieve sender reputation score (0-100)

Path Parameters:

  • id (required) - DashClicks account ID

Sendgrid API:

GET https://api.sendgrid.com/v3/subusers/reputations?usernames={username}
Authorization: Bearer {SENDGRID_API_KEY}

Response:

{
"success": true,
"message": "SUCCESS",
"data": [
{
"username": "dashclicks_acc_507f191e",
"reputation": 99.8
}
]
}

Reputation Score Interpretation:

  • 95-100: Excellent - high deliverability
  • 80-94: Good - acceptable deliverability
  • 70-79: Fair - may experience issues
  • Below 70: Poor - high bounce/spam rates

๐ŸŒ Domain Managementโ€‹

Overviewโ€‹

Custom domains improve email deliverability and branding by allowing emails to be sent from your own domain (e.g., @yourdomain.com) instead of Sendgrid's shared domains.

Domain Authentication Benefits:

  • โœ‰๏ธ Better deliverability rates
  • ๐Ÿ”’ Enhanced security (SPF, DKIM, DMARC)
  • ๐ŸŽจ Branded sender addresses
  • ๐Ÿ“Š Improved sender reputation
  • ๐Ÿ›ก๏ธ Reduced spam complaints

Add Domain to Subuserโ€‹

Endpoint: POST /v1/integrations/sendgrid/subusers/domains

Purpose: Add custom domain to subuser for authenticated sending

Request Body:

{
"domain": "dashclicks.com",
"subdomain": "mail"
}

Validation:

  • domain: Required string (valid domain format)
  • subdomain: Required string (subdomain prefix)

Sendgrid API:

POST https://api.sendgrid.com/v3/whitelabel/domains
Authorization: Bearer {SENDGRID_API_KEY}
On-Behalf-Of: {subuser_username}
Content-Type: application/json

{
"domain": "dashclicks.com",
"subdomain": "mail",
"automatic_security": false
}

Process:

  1. Get subuser from account document
  2. Create domain via Sendgrid API (on-behalf-of subuser)
  3. Auto-add DMARC record:
    {
    type: 'txt',
    host: '_dmarc.dashclicks.com',
    data: 'v=DMARC1;p=none',
    valid: false
    }
  4. Push to account.sendgrid.domains array in database

Response:

{
"success": true,
"message": "SUCCESS",
"data": [
{
"id": 12345678,
"domain": "dashclicks.com",
"subdomain": "mail",
"valid": false,
"dns": {
"mail_cname": {
"host": "mail.dashclicks.com",
"type": "CNAME",
"data": "u12345678.wl.sendgrid.net",
"valid": false
},
"dkim1": {
"host": "s1._domainkey.dashclicks.com",
"type": "CNAME",
"data": "s1.domainkey.u12345678.wl.sendgrid.net",
"valid": false
},
"dkim2": {
"host": "s2._domainkey.dashclicks.com",
"type": "CNAME",
"data": "s2.domainkey.u12345678.wl.sendgrid.net",
"valid": false
},
"dmarc": {
"host": "_dmarc.dashclicks.com",
"type": "TXT",
"data": "v=DMARC1;p=none",
"valid": false
}
}
}
]
}

DNS Configurationโ€‹

After adding a domain, configure the following DNS records in your domain registrar:

1. Mail CNAME Record:

Host: mail.dashclicks.com
Type: CNAME
Value: u12345678.wl.sendgrid.net
TTL: 3600

2. DKIM1 CNAME Record:

Host: s1._domainkey.dashclicks.com
Type: CNAME
Value: s1.domainkey.u12345678.wl.sendgrid.net
TTL: 3600

3. DKIM2 CNAME Record:

Host: s2._domainkey.dashclicks.com
Type: CNAME
Value: s2.domainkey.u12345678.wl.sendgrid.net
TTL: 3600

4. DMARC TXT Record:

Host: _dmarc.dashclicks.com
Type: TXT
Value: v=DMARC1;p=none
TTL: 3600

DNS Propagation Time: 5-30 minutes (varies by DNS provider)

Validate Domainโ€‹

Endpoint: POST /v1/integrations/sendgrid/subusers/domains/:domain_id/validate

Purpose: Verify DNS records are correctly configured

Path Parameters:

  • domain_id (required) - Sendgrid domain ID

Sendgrid API:

POST https://api.sendgrid.com/v3/whitelabel/domains/{domain_id}/validate
Authorization: Bearer {SENDGRID_API_KEY}
On-Behalf-Of: {subuser_username}

Response:

{
"success": true,
"message": "SUCCESS",
"data": {
"id": 12345678,
"valid": true,
"validation_results": {
"mail_cname": {
"valid": true,
"reason": null
},
"dkim1": {
"valid": true,
"reason": null
},
"dkim2": {
"valid": true,
"reason": null
}
}
}
}

Validation Failures:

{
"success": true,
"message": "SUCCESS",
"data": {
"id": 12345678,
"valid": false,
"validation_results": {
"mail_cname": {
"valid": false,
"reason": "Expected CNAME to match u12345678.wl.sendgrid.net but found none."
},
"dkim1": {
"valid": true,
"reason": null
},
"dkim2": {
"valid": true,
"reason": null
}
}
}
}

Common Validation Errors:

ErrorCauseSolution
CNAME not foundDNS not configuredAdd DNS records
CNAME value mismatchIncorrect valueUpdate to correct Sendgrid value
DNS not propagatedWaiting for propagationWait 5-30 minutes, retry validation
TTL too highSlow updatesReduce TTL to 3600 or lower
Multiple CNAME recordsDuplicate recordsRemove duplicates, keep one
Wrong subdomain configuredTypo in subdomainDelete and recreate with correct

Delete Domainโ€‹

Endpoint: DELETE /v1/integrations/sendgrid/subusers/domains/:domain_id

Purpose: Remove domain from subuser

Path Parameters:

  • domain_id (required) - Sendgrid domain ID

Process:

  1. Verify domain belongs to subuser
  2. Delete via Sendgrid API:
    DELETE https://api.sendgrid.com/v3/whitelabel/domains/{domain_id}
    Authorization: Bearer {SENDGRID_API_KEY}
    On-Behalf-Of: {subuser_username}
  3. Update database to remove domain from array
  4. Delete associated user emails from user.sendgrid_emails

Response:

{
"success": true,
"message": "Domain deleted successfully"
}

๐Ÿ“ฆ SubUserCollection Modelโ€‹

Purpose: Subuser and domain document management

Methods:

getSubUserByAccountID()โ€‹

SubUserCollection.getSubUserByAccountID(accountID);
// Returns: { isEmpty: boolean, doc: account._doc }

getSubUserByUserID()โ€‹

SubUserCollection.getSubUserByUserID(userID);
// Returns: { isEmpty: boolean, doc: account._doc }

getSubUserDocByUsername()โ€‹

SubUserCollection.getSubUserDocByUsername(username);
// Returns: { isEmpty: boolean, doc: account._doc }

addSubUserDoc()โ€‹

SubUserCollection.addSubUserDoc({
account_id,
sendgrid: {
subuser: { username, user_id, email, disabled },
domain_assigned: true,
domains: [],
},
});
// Returns: subuser object

deleteSubUserDoc()โ€‹

SubUserCollection.deleteSubUserDoc(docID);
// Sets sendgrid=null on account

updateSubUserStatusDoc()โ€‹

SubUserCollection.updateSubUserStatusDoc(docID, disabled);
// Updates sendgrid.subuser.disabled

getSubUserDomainDocByUserID()โ€‹

SubUserCollection.getSubUserDomainDocByUserID(userID, domainID);
// Returns: { isEmpty: boolean, doc: account._doc }

addSubUserDomainDoc()โ€‹

SubUserCollection.addSubUserDomainDoc(docID, sendgridDomain);
// Adds DMARC DNS record automatically
// Pushes to sendgrid.domains array

updateDomain()โ€‹

SubUserCollection.updateDomain(docID, domainStatus);
// Updates DNS validation results
// Returns: { isEmpty: boolean, doc: domain }

deleteSubUserDomainDoc()โ€‹

SubUserCollection.deleteSubUserDomainDoc(docID, newDomains);
// Replaces entire domains array

deleteUserEmailDoc()โ€‹

SubUserCollection.deleteUserEmailDoc(userId, emails);
// Pulls emails from user.sendgrid_emails array

๐ŸŽ›๏ธ SubUserControllerโ€‹

Location: Controllers/SubUserController.js

Key Methodsโ€‹

createSubUsers()โ€‹

  • Route: POST /v1/integrations/sendgrid/subusers
  • Validation: { username: string.required, email: email.required }
  • Logic: Generate password โ†’ Get IP โ†’ Create subuser โ†’ Assign domain โ†’ Store in DB

updateSubUser()โ€‹

  • Route: PUT /v1/integrations/sendgrid/subusers/:id
  • Body: { disabled: boolean }
  • Logic: Get subuser โ†’ Update via API โ†’ Update database

deleteSubUser()โ€‹

  • Route: DELETE /v1/integrations/sendgrid/subusers/:id
  • Logic: Get username โ†’ Delete via API โ†’ Remove from database

getSubUserReputation()โ€‹

  • Route: GET /v1/integrations/sendgrid/subusers/:id/reputation
  • Logic: Query Sendgrid reputation API โ†’ Return score

subUserAddDomain()โ€‹

  • Route: POST /v1/integrations/sendgrid/subusers/domains
  • Logic: Get subuser โ†’ Create domain โ†’ Auto-add DMARC โ†’ Update DB

subUserValidateDomain()โ€‹

  • Route: POST /v1/integrations/sendgrid/subusers/domains/:domain_id/validate
  • Logic: Validate via API โ†’ Update validation status in DB

subUserDeleteDomain()โ€‹

  • Route: DELETE /v1/integrations/sendgrid/subusers/domains/:domain_id
  • Logic: Verify ownership โ†’ Delete via API โ†’ Remove from DB โ†’ Delete user emails

๐Ÿงช Testingโ€‹

Test Subuser Creationโ€‹

curl -X POST http://localhost:5003/v1/e/sendgrid/subusers \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"username": "dashclicks_test_acc",
"email": "subuser@test.com"
}'

Test Domain Additionโ€‹

curl -X POST http://localhost:5003/v1/e/sendgrid/subusers/domains \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"domain": "test.com",
"subdomain": "mail"
}'

Test Domain Validationโ€‹

curl -X POST http://localhost:5003/v1/e/sendgrid/subusers/domains/12345678/validate \
-H "Authorization: Bearer {jwt_token}"

Test Reputation Checkโ€‹

curl -X GET http://localhost:5003/v1/e/sendgrid/subusers/{account_id}/reputation \
-H "Authorization: Bearer {jwt_token}"

โš ๏ธ Important Notesโ€‹

  • ๐Ÿข One Subuser Per Account: Each DashClicks account gets exactly one subuser
  • ๐Ÿ”‘ Random Passwords: Passwords auto-generated for security
  • ๐Ÿ“ง Default Domain: Subusers automatically assigned default Sendgrid domain
  • ๐ŸŒ Custom Domains: Optional - improves deliverability and branding
  • โœ… DNS Validation Required: Domains must be validated before use
  • ๐Ÿ“Š Reputation Tracking: Monitor reputation to maintain high deliverability
  • ๐Ÿ”’ IP Assignment: Each subuser assigned dedicated or shared IP
  • โš™๏ธ DMARC Auto-Config: DMARC record automatically added (v=DMARC1;p=none)
  • ๐Ÿ—‘๏ธ Soft Delete: Subuser deletion sets sendgrid: null (preserves history)
  • ๐Ÿ”„ Domain Reassignment: Domains can be moved between subusers

๐Ÿ“ˆ Best Practicesโ€‹

Subuser Managementโ€‹

  1. Create Early: Set up subuser during account onboarding
  2. Monitor Reputation: Check regularly (weekly/monthly)
  3. Use Descriptive Usernames: Follow naming convention (e.g., dashclicks_acc_{id})
  4. Enable/Disable vs Delete: Use enable/disable for temporary suspension

Domain Configurationโ€‹

  1. Verify DNS Access: Ensure customer can modify DNS records
  2. Use Short TTL: Set TTL to 3600 for faster changes
  3. Validate After Propagation: Wait 5-30 minutes before validating
  4. Monitor Validation Status: Re-validate periodically
  5. Use Subdomains: Recommend mail. or email. subdomain

Reputation Managementโ€‹

  1. Start Slow: Gradually increase sending volume for new subusers
  2. Monitor Bounces: High bounce rate damages reputation
  3. Respect Unsubscribes: Process immediately to avoid spam complaints
  4. Use Double Opt-In: Confirm email addresses before adding to list
  5. Clean Lists Regularly: Remove inactive/invalid addresses

๐Ÿšจ Troubleshootingโ€‹

Domain Validation Failingโ€‹

Diagnosis:

  1. Check DNS records are configured:

    dig mail.yourdomain.com CNAME
    dig s1._domainkey.yourdomain.com CNAME
    dig s2._domainkey.yourdomain.com CNAME
    dig _dmarc.yourdomain.com TXT
  2. Wait for DNS propagation (5-30 minutes)

  3. Retry validation endpoint

  4. Check Sendgrid dashboard for validation status

Low Reputation Scoreโ€‹

Common Causes:

  • High bounce rate (>5%)
  • Spam complaints (>0.1%)
  • Sending to unverified emails
  • Rapid volume increase
  • Poor list hygiene

Solutions:

  • Clean email list
  • Enable double opt-in
  • Monitor DND list
  • Reduce sending volume temporarily
  • Improve email content quality
๐Ÿ’ฌ

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM