Skip to main content

Generative Prompt Parameters — Complete Parameters & Flow Reference

Audience: Developers & Operations Team
Updated: 2026-07-29
Key Files: TaskGenerativeTemplates.cs, HyperPersonaliseRequest.cs, HyperPersonaliseRequestModel.cs, HyperRequestService.cs, GenerativeTemplatesController.cs


Table of Contents

  1. Overview
  2. End-to-End Mermaid Flow
  3. Sender Parameters
  4. Recipient Parameters
  5. Template & Prompt Parameters
  6. Campaign & Client Metadata
  7. Additional Instructions (The additionalData Dictionary)
  8. Buyer Intent & Engagement Signals
  9. Previous Email Chain (Chasers)
  10. AI Provider & Model Selection
  11. Batch vs Single Processing
  12. Response & Logging
  13. Data Point Gating

Overview

The generative email pipeline builds AI-personalised emails by assembling a rich prompt payload from multiple data sources. The payload is constructed in TaskGenerativeTemplates (or TaskGenerativeTemplatesBulk for batch), serialised to JSON via HyperPersonaliseRequestModel, and POSTed to the AI Middleware service at {AIMUrl}/api/v5/generative/generate.

Every parameter passed to the AI is a property on HyperPersonaliseRequestModel. The model is built from HyperPersonaliseRequest (Dapper layer) via the GenerateHyperModel() helper.


End-to-End Mermaid Flow


Sender Parameters

These describe the sending company and the individual sender. All values are HTML-stripped before being sent to the AI.

#ParameterTypeSourceDescription
1SenderCompanystringEmail Profile / ClientName of the sending company
2SenderCompanyDescriptionstringEmail ProfileWhat the company does; HTML-stripped
3SenderOfferingstringEmail ProfileProduct/service offering description; HTML-stripped
4SenderAnglestringEmail ProfileValue proposition / angle; HTML-stripped
5SenderUSPsstringEmail ProfileUnique selling points; HTML-stripped
6SenderTonestringEmail ProfileDesired email tone (e.g. "professional", "friendly"); HTML-stripped
7SenderNamestringEmail ProfileFull name of the sender (sales agent)
8SenderJobTitlestringEmail ProfileJob title of the sender
9SenderWebsitestringEmail ProfileCompany website URL

Brand & Market Context (in additionalData)

#KeyTypeEnumDescription
10BrandFamiliarityIdstringBrandFamiliarityEnumHow well the recipient knows the brand (0 = not set)
11BrandFamiliarityDescriptionstring-Human-readable label for brand familiarity
12AudienceAwarenessOfOfferingIdstringMarketSaturationEnumMarket awareness of the offering (0 = not set)
13AudienceAwarenessOfOfferingDescriptionstring-Human-readable label for market saturation

Recipient Parameters

These describe the target prospect and their company.

#ParameterTypeSourceDescription
14RecipientNamestringProspect recordFull name of the recipient
15RecipientFirstNamestringProspect recordFirst name only
16RecipientEmailstringProspect recordEmail address
17RecipientJobTitlestringProspect recordCurrent job title
18RecipientLinkedInstringProspect recordLinkedIn profile URL
19RecipientCompanystringProspect recordCompany name
20RecipientCompanyDescriptionstringProspect record / enrichmentDescription of the recipient's company
21RecipientCompanyIndustrystringProspect recordIndustry classification
22RecipientCompanySizestringProspect recordCompany employee count / size range
23RecipientCompanyCountrystringProspect recordCountry of the company
24RecipientDomainstringProspect recordCompany website domain

Template & Prompt Parameters

These control how the AI generates the email — the prompt structure, style, and context.

#ParameterTypeRequiredDescription
25SettingIdint?NoMaster template / prompt setting ID. Determines the AI system prompt and output structure.
26Introstring?NoCustom intro inserted at the top of the prompt. Supported only by certain settings.
27AdditionalInstructionsstring?NoTemplate-level extra instructions appended to the prompt (e.g. "mention the upcoming webinar").
28IsManualboolYesIf true, the email was manually triggered (portal preview). If false, automated via queue.
29CommonTemplateIdint?NoShared template ID for consistent styling across stages.
30FallbackEmailstringNoThe standard (non-AI) email used if generation fails. Stripped of signature and unsubscribe.
31PreviousEmailstring?NoChasers only: Full text of previous emails in the thread. Format: Email N:\n"content"\n.
32rtlTextDirectionboolYesIf true, generated HTML uses right-to-left text direction.
33TagstringYesStage tag, e.g. M1 (stage 1), M2 (stage 2). Used for AI routing.

Campaign & Client Metadata

These provide contextual identifiers for logging, routing, and tracking.

#ParameterTypeDescription
34ProspectIdint?Prospect primary key
35ClientIdintClient account ID
36CampaignIdintCampaign ID
37CampaignNamestringCampaign display name
38ClientNamestringClient account display name
39EmailProfileIdintEmail profile (sender identity) ID
40EmailprofileNamestringEmail profile display name
41EmailTempalteIdint?Email template (stage template) ID
42ExternalIdintProspectGenerativeLogDetails.Id — links the AI request to the logging record
43UnsubscribeContentstringHTML unsubscribe footer (custom per client)
44UnsubscribeContentTextstringPlain-text unsubscribe footer

Additional Instructions (The additionalData Dictionary)

The additionalData dictionary carries key-value pairs that the AI Middleware interprets as additional instruction dimensions. These are not part of the main prompt body — they are sent as a structured dictionary that the AI provider settings consume.

Always Present

KeyValueSourceDescription
statestringProspect enrichmentUS state of the prospect's company (e.g. "California")
AudienceSpecificAdditionalInstructionsstring?Audience builder / CampaignCampaign-level audience description (e.g. "CTOs at SaaS companies"). Gated by DataPointsEnum.AudienceSpecificAdditionalInstructions. Set to null if data point not enabled.
ApproachLevelAdditionalInstructionsstring?Email Profile → Campaign settingsCampaign-level instructions set in the email profile (e.g. "Keep it under 150 words"). HTML-stripped.
AudienceAwarenessOfOfferingIdstringCampaign settingsEnum value for market saturation (empty if 0).
AudienceAwarenessOfOfferingDescriptionstringCampaign settingsFriendly name for market saturation level.
BrandFamiliarityIdstringCampaign settingsEnum value for brand familiarity (empty if 0).
BrandFamiliarityDescriptionstringCampaign settingsFriendly name for brand familiarity level.

Conditionally Present

KeyValueConditionDescription
ChaserTypestringFollow-up stages onlyChaser type ID selected by ChaserTypes.GetChaserType(). Determines the follow-up strategy (e.g. "case study", "social proof", "OOO response").
hasOOOReturnDate"True"/"False"Prospect has OOO responseWhether the prospect's OOO auto-reply included a return date.
OOOReturnDaysstring (int)HasOOOReturnDate == trueNumber of days until the prospect returns, calculated as OOOReturnDate - LastResponderDate.

LinkedIn Prospect Parameters

When ProspectSource == "LinkedIn" and ProspectParametars is not empty, the JSON-deserialised parameters are added to additionalData with PascalCase keys. A blacklist (IsExcluded()) filters out sensitive/internal keys.

Example LinkedIn parameters injected:

CurrentCompany, CurrentPosition, Location, Industry, Connections, ...

Buyer Intent & Engagement Signals

These are optional fields — they are only populated if the email template's DataPoints field includes the corresponding DataPointsEnum flag. If the data point is not enabled, the field is set to null and excluded from the prompt.

#ParameterTypeDataPointsEnum FlagDescription
45RecipientCompanyAlternativeQualifiedProspectsstring?FutureAlternative (3)Other prospects at the same company that could be contacted in future.
46RecipientCompanyRecentlyContactedProspectsstring?RecentlyEngaged (2)Other prospects at the same company recently contacted.
47RecipientCompanyHasShownBuyerIntentLast30Daysbool?RecentWebVisitCompany (6)Whether the recipient's company visited the sender's website in the last 30 days.
48RecipientCompanyHasShownBuyerIntentLast90Daysbool?RecentWebVisitCompany (6)Whether the recipient's company visited in the last 90 days.
49RecipientHasShownBuyerIntentLast30Daysbool?RecentWebVisitIndividual (5)Whether the individual recipient visited the sender's website in the last 30 days.
50RecipientHasShownBuyerIntentLast90Daysbool?RecentWebVisitIndividual (5)Whether the individual recipient visited in the last 90 days.

Data Point Gating Logic

if DataPoints.CheckIfExist(emailTemplate.DataPoints, DataPointsEnum.FutureAlternative)
→ populate RecipientCompanyAlternativeQualifiedProspects
else
→ set to null

if DataPoints.CheckIfExist(emailTemplate.DataPoints, DataPointsEnum.AudienceSpecificAdditionalInstructions)
→ keep AudienceDescription populated
else
→ set AudienceDescription = null AND null out additionalData["AudienceSpecificAdditionalInstructions"]

Previous Email Chain (Chasers)

For follow-up emails (stages 2+), the AI receives the full chain of previous messages:

How PreviousEmail Is Built

  1. Query EmailTemplateProspect for all previous stages (stage - 1, stage - 2, ...)
  2. For each previous message:
    • Strip signature (*|SALES_AGENT_SIGNATURE|*) and "From:" header
    • Format as: Email {sendNumber}:\n"{textContent}"\n
  3. Concatenate all previous messages, newest last
  4. If the generated chaser contains [PREVIOUS MESSAGE], it's replaced with the real content in the final saved template

Example chain sent to AI for stage 3:

Email 1:
"Hi John, noticed you're the CTO at Acme Corp..."

Email 2:
"Following up on my previous email about our DevOps solution..."

AI Provider & Model Selection

The AI provider and model are determined server-side by the AI Middleware (email-template-demo) based on the SettingId and prompt configuration. The Sopro core does not specify a model — it receives the model name back in the response.

Supported AI Providers

ProviderModels (examples)
OpenAIGPT-4o, GPT-4o-mini, GPT-4 Turbo
DeepSeekDeepSeek-V3, DeepSeek-R1
GrokGrok-2
AnthropicClaude 3.5 Sonnet, Claude 3 Opus

Model Tracking

The model used is recorded in:

  • ProspectGenerativeLogDetails.Model — per-prospect
  • EndpointManagerLog (ClickHouse) — per-request in email-template-demo

Batch vs Single Processing

Single Prospect Path

TaskGenerativeTemplates
→ GenerateHyperModel()
→ HyperRequestService.HyperPersonaliseRequest(model)
→ POST {AIMUrl}/api/v5/generative/generate (JSON body: HyperPersonaliseRequestModel)
→ AI generates email synchronously
→ Returns HyperTemplateResponse immediately

Batch/Bulk Path

TaskGenerativeTemplatesBulk
→ Save all HyperPersonaliseRequestModel as JSONL to Azure Blob
→ HyperRequestService.CreateHyperBatch(fileName)
→ POST {AIMUrl}/api/v5/batch-processing/createHyperBatch
→ Creates BatchPromptRequest (GUID)
→ Hangfire processes batch asynchronously
→ Polls every ~10 min via ProcessAllPendingHyperBatch
→ On complete → WebHookProcessResponceHyperBatch
→ POST SoProCoreAPI/api/GenerativeTemplates/ProcessResponceHyperBatch
→ Enqueues ProcessResponceHyperBatch in SoProQueue
→ GenerativeTemplatesController.HyperBatch(Guid Id)
→ GetHyperBatch(batchId) → updates GenerativeBatchLog
→ For each TemplateResponse → processes same as single

Decision: Single vs Batch

emailProfile.IsBatch && canBatch(settingsId)
→ YES: GenerativeTemplatesBulk queue
→ NO: GenerativeTemplates queue

Response & Logging

HyperTemplateResponse (from AI)

FieldTypeDescription
SuccessboolWhether generation succeeded
HtmlstringFull HTML email body
TemplatestringPlain-text version
SubjectstringAI-generated subject line
ModelstringAI model used (e.g. "gpt-4o")
LogIdGuid?AI log correlation ID
UsageUsageInfoToken counts and estimated cost
ErrorsList<string>Error messages if failed

UsageInfo

FieldTypeDescription
PromptTokensintTokens consumed by the prompt
CompletionTokensintTokens generated in the response
EstimatedCostdecimalEstimated USD cost

Post-Processing (on success)

  1. Signature (*|SALES_AGENT_SIGNATURE|*) appended to HTML
  2. Unsubscribe link appended (custom or default)
  3. Morning/Afternoon merge tags normalised to *|SENDSCHEDULE_*|* format
  4. For chasers: previous email chain variables (*|SEND{N}_DATE|*, *|SEND{N}_SUBJECT|*, *|SEND{N}_HTML_CONTENT|*) injected
  5. Final HTML uploaded to Azure Blob: {container}/GPTSpindle/{emailTemplateProspectId}
  6. EmailTemplateProspect record created/updated with TextContent and Subject
  7. ProspectGenerativeLogDetails logged with tokens, cost, model, success/failure

On Failure

  • EmailTemplateProspect is NOT created
  • ProspectGenerativeLogDetails.Success = false, EmailTemplateProspectId = NULL
  • Error logged to DapperApplicationsErrorLog
  • At send time, the system falls back to the standard EmailTemplate.HTMLContent

Data Point Gating

Not all parameters are sent for every generation. The DataPoints field on the email template (a comma-separated string of DataPointsEnum values) determines which parameters are populated:

DataPointsEnumValueControls
RecentlyEngaged2RecipientCompanyRecentlyContactedProspects
FutureAlternative3RecipientCompanyAlternativeQualifiedProspects
AudienceSpecificAdditionalInstructions4AudienceDescription + additionalData["AudienceSpecificAdditionalInstructions"]
RecentWebVisitIndividual5RecipientHasShownBuyerIntentLast30Days, RecipientHasShownBuyerIntentLast90Days
RecentWebVisitCompany6RecipientCompanyHasShownBuyerIntentLast30Days, RecipientCompanyHasShownBuyerIntentLast90Days

Complete Parameters Summary

#ParameterCategoryAlways SentGated
1SenderCompanySender-
2SenderCompanyDescriptionSender-
3SenderOfferingSender-
4SenderAngleSender-
5SenderUSPsSender-
6SenderToneSender-
7SenderNameSender-
8SenderJobTitleSender-
9SenderWebsiteSender-
10BrandFamiliarityIdadditionalData-
11BrandFamiliarityDescriptionadditionalData-
12AudienceAwarenessOfOfferingIdadditionalData-
13AudienceAwarenessOfOfferingDescriptionadditionalData-
14RecipientNameRecipient-
15RecipientFirstNameRecipient-
16RecipientEmailRecipient-
17RecipientJobTitleRecipient-
18RecipientLinkedInRecipient-
19RecipientCompanyRecipient-
20RecipientCompanyDescriptionRecipient-
21RecipientCompanyIndustryRecipient-
22RecipientCompanySizeRecipient-
23RecipientCompanyCountryRecipient-
24RecipientDomainRecipient-
25SettingIdTemplate-
26IntroTemplate-
27AdditionalInstructionsTemplate-
28IsManualTemplate-
29CommonTemplateIdTemplate-
30FallbackEmailTemplate-
31PreviousEmailTemplateChasers only-
32rtlTextDirectionTemplate-
33TagTemplate-
34-44Metadata (ProspectId, ClientId, CampaignId, etc.)Metadata-
45RecipientCompanyAlternativeQualifiedProspectsBuyer Intent-FutureAlternative
46RecipientCompanyRecentlyContactedProspectsBuyer Intent-RecentlyEngaged
47RecipientCompanyHasShownBuyerIntentLast30DaysBuyer Intent-RecentWebVisitCompany
48RecipientCompanyHasShownBuyerIntentLast90DaysBuyer Intent-RecentWebVisitCompany
49RecipientHasShownBuyerIntentLast30DaysBuyer Intent-RecentWebVisitIndividual
50RecipientHasShownBuyerIntentLast90DaysBuyer Intent-RecentWebVisitIndividual
51AudienceSpecificAdditionalInstructionsadditionalData-AudienceSpecificAdditionalInstructions
52ApproachLevelAdditionalInstructionsadditionalData-
53ChaserTypeadditionalDataChasers only-
54hasOOOReturnDateadditionalDataOOO only-
55OOOReturnDaysadditionalDataOOO only-
56LinkedIn parametersadditionalDataLinkedIn source only-
57stateadditionalData-

Three Layers of "Additional Instructions"

The system supports three distinct layers of additional instructions, each applied at a different scope:


API Endpoint Reference

Single Generation

POST {AIMUrl}/api/v5/generative/generate
Headers: accept: application/json, auth: {AIMKey}
Body: HyperPersonaliseRequestModel (JSON)
Response: HyperTemplateResponse (JSON)

Batch Create

POST {AIMUrl}/api/v5/batch-processing/createHyperBatch?FileName={file}
Headers: accept: application/json, auth: {AIMKey}
Response: Guid (BatchRequestId)

Batch Status

POST {AIMUrl}/api/v5/batch-processing/getHyperBatch?Id={batchId}
Headers: accept: application/json, auth: {AIMKey}
Response: BatchHyperResult (JSON)

Callback (from AI Middleware → Sopro Core)

POST {SoProCoreUrl}/api/GenerativeTemplates/HyperBatch?Id={batchId}
Response: IActionResult

Can Batch Check

POST {AIMUrl}/api/v5/generative/canBatch?SettingsId={id}
Headers: accept: application/json, auth: {AIMKey}
Response: bool

End of Generative Prompt Parameters Reference