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โ
| Endpoint | Method | Scope | Description |
|---|---|---|---|
/v1/integrations/sendgrid/subusers | POST | communications | Create new subuser |
/v1/integrations/sendgrid/subusers/:id | PUT | communications | Enable/disable subuser |
/v1/integrations/sendgrid/subusers/:id | DELETE | communications | Delete subuser |
/v1/integrations/sendgrid/subusers/:id/reputation | GET | communications | Get subuser reputation score |
Domain Operationsโ
| Endpoint | Method | Scope | Description |
|---|---|---|---|
/v1/integrations/sendgrid/subusers/domains | POST | accounts.email_custom_domain, accounts | Add domain to subuser |
/v1/integrations/sendgrid/subusers/domains/:domain_id | DELETE | accounts.email_custom_domain, accounts | Delete subuser domain |
/v1/integrations/sendgrid/subusers/domains/:domain_id/validate | POST | accounts.email_custom_domain, accounts | Validate 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 stringemail: Required email format
Process:
-
Generate Password: Random 10 characters + "1D" suffix
const password = Math.random().toString(36).substring(2, 12) + '1D'; -
Get Available IP: Query Sendgrid for available IP addresses
GET https://api.sendgrid.com/v3/ips
Authorization: Bearer {SENDGRID_API_KEY} -
Check Existing: Verify subuser doesn't already exist in database
-
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"]
} -
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"
} -
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:
- Get subuser username from database
- Delete via Sendgrid API:
DELETE https://api.sendgrid.com/v3/subusers/{username}
Authorization: Bearer {SENDGRID_API_KEY} - 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:
- Get subuser from account document
- Create domain via Sendgrid API (on-behalf-of subuser)
- Auto-add DMARC record:
{
type: 'txt',
host: '_dmarc.dashclicks.com',
data: 'v=DMARC1;p=none',
valid: false
} - Push to
account.sendgrid.domainsarray 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:
| Error | Cause | Solution |
|---|---|---|
| CNAME not found | DNS not configured | Add DNS records |
| CNAME value mismatch | Incorrect value | Update to correct Sendgrid value |
| DNS not propagated | Waiting for propagation | Wait 5-30 minutes, retry validation |
| TTL too high | Slow updates | Reduce TTL to 3600 or lower |
| Multiple CNAME records | Duplicate records | Remove duplicates, keep one |
| Wrong subdomain configured | Typo in subdomain | Delete 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:
- Verify domain belongs to subuser
- Delete via Sendgrid API:
DELETE https://api.sendgrid.com/v3/whitelabel/domains/{domain_id}
Authorization: Bearer {SENDGRID_API_KEY}
On-Behalf-Of: {subuser_username} - Update database to remove domain from array
- 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โ
- Create Early: Set up subuser during account onboarding
- Monitor Reputation: Check regularly (weekly/monthly)
- Use Descriptive Usernames: Follow naming convention (e.g.,
dashclicks_acc_{id}) - Enable/Disable vs Delete: Use enable/disable for temporary suspension
Domain Configurationโ
- Verify DNS Access: Ensure customer can modify DNS records
- Use Short TTL: Set TTL to 3600 for faster changes
- Validate After Propagation: Wait 5-30 minutes before validating
- Monitor Validation Status: Re-validate periodically
- Use Subdomains: Recommend
mail.oremail.subdomain
Reputation Managementโ
- Start Slow: Gradually increase sending volume for new subusers
- Monitor Bounces: High bounce rate damages reputation
- Respect Unsubscribes: Process immediately to avoid spam complaints
- Use Double Opt-In: Confirm email addresses before adding to list
- Clean Lists Regularly: Remove inactive/invalid addresses
๐จ Troubleshootingโ
Domain Validation Failingโ
Diagnosis:
-
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 -
Wait for DNS propagation (5-30 minutes)
-
Retry validation endpoint
-
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