UC-007 — Manage Contacts and Lists for Campaigns
| Field | Value |
|---|---|
| ID | UC-007 |
| Goal | Import contacts, create segmented lists, and prepare them for use in campaigns |
| Channel | All |
| Complexity | Intermediate |
| Estimated time | 20 minutes |
| APIs involved | POST/GET/PUT/DELETE /api/partner-gateway/v1/contacts, POST/GET /contacts/list, POST /contacts/list/contacts, POST /contacts/upload, POST /contacts/upload/vcard |
Real-world scenarios
- ShopItalia — Customer address book import: Import the export from the company CRM (CSV with 5,000 customers) into the platform to prepare the Black Friday campaign.
- TurismoVeneto — Regional segmentation: Create separate lists for customers in Lombardia, Veneto, and Emilia-Romagna to send geo-targeted promotions on summer stays.
- Studio Legale Ferrara — Phone address book: Import the corporate address book in VCard format to send institutional communications via SMS.
Prerequisites
Before you begin, make sure you have:
- Active API Key → How to get one
- Sufficient credit → Check in the Qlara Dashboard
- CSV or VCard file ready for import
:::tip Test without costs
Add "simulation": true in the request body to validate the flow without actually sending messages and without consuming credit.
:::
Contact management flow
The diagram shows the three import paths: manual addition, CSV/Excel upload, or VCard import. All converge into verification and campaign use.
Step 1 — Create a contact list
Create an empty list that will serve as a container for the contacts.
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/list \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"name": "Clienti Nord Italia",
"description": "Clienti delle regioni Lombardia, Piemonte, Veneto, Emilia-Romagna"
}'
Response — List created
{
"id": 87,
"name": "Clienti Nord Italia",
"description": "Clienti delle regioni Lombardia, Piemonte, Veneto, Emilia-Romagna",
"contactCount": 0,
"createdAt": "2026-04-09T09:00:00Z"
}
:::tip Save the list ID
The id field is the identifier you will use to add contacts and associate the list with campaigns.
:::
Step 2a — Add contacts individually
Create a new contact in the address book and associate it with the list.
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"firstName": "Giulia",
"lastName": "Rossi",
"phoneNumber": "+393401234567",
"email": "giulia.rossi@example.it",
"gender": "F",
"city": "Milano",
"province": "MI"
}'
Response — Contact created
{
"id": 24501,
"firstName": "Giulia",
"lastName": "Rossi",
"phoneNumber": "+393401234567",
"email": "giulia.rossi@example.it",
"gender": "F",
"city": "Milano",
"province": "MI",
"valid": true,
"createdAt": "2026-04-09T09:01:00Z"
}
Associate the contact with the list:
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/list/contacts \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"contactIds": [24501],
"listIds": [87]
}'
{
"added": 1,
"skipped": 0
}
:::info Multiple addition
You can pass multiple contactIds and multiple listIds in a single request to associate N contacts with M lists at once.
:::
Step 2b — Bulk import from CSV
For mass imports, upload a CSV or Excel file. The process happens in two phases: upload with preview, then mapping confirmation.
Expected CSV format
nome,cognome,telefono,email,citta
Marco,Bianchi,+393489876543,m.bianchi@example.it,Torino
Anna,Verdi,+393331122334,anna.verdi@example.it,Bologna
Luca,Neri,+393201234567,l.neri@example.it,Milano
Phase 1 — Upload and preview
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/upload \
-H "X-Api-Key: YOUR_API_KEY" \
-F "file=@clienti_nord_italia.csv" \
-F "listId=87"
Response — File analyzed
{
"uploadId": "upl-a1b2c3d4",
"fileName": "clienti_nord_italia.csv",
"totalRows": 5230,
"parsedRows": 5230,
"columns": ["nome", "cognome", "telefono", "email", "citta"],
"preview": [
{
"nome": "Marco",
"cognome": "Bianchi",
"telefono": "+393489876543",
"email": "m.bianchi@example.it",
"citta": "Torino"
},
{
"nome": "Anna",
"cognome": "Verdi",
"telefono": "+393331122334",
"email": "anna.verdi@example.it",
"citta": "Bologna"
}
]
}
Phase 2 — Confirm column mapping
Map the CSV columns to system fields and confirm the import:
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/mapped/file \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"uploadId": "upl-a1b2c3d4",
"mapping": {
"nome": "firstName",
"cognome": "lastName",
"telefono": "phoneNumber",
"email": "email",
"citta": "city"
},
"listId": 87
}'
Response — Import completed
{
"imported": 5104,
"duplicates": 98,
"invalid": 28,
"listId": 87,
"totalInList": 5105
}
Behind the scenes — CSV import process
- Upload and parsing: The file is uploaded and analyzed. The system identifies the columns and returns a preview. No contacts are created yet.
- Mapping and confirmation: You confirm the column-to-field mapping. Only at this point are contacts created and associated with the list.
- Number validation: Numbers are validated in international format. Malformed numbers or those without a prefix are discarded.
- Deduplication: Contacts with the same phone number are counted as
duplicatesand not inserted again.
This two-phase approach prevents errors: you can verify that columns are correctly mapped before committing thousands of records.
Step 2c — Import from VCard
To import contacts from a phone address book in .vcf format:
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/upload/vcard \
-H "X-Api-Key: YOUR_API_KEY" \
-F "file=@rubrica_aziendale.vcf" \
-F "listId=87"
Response — VCard analyzed
{
"uploadId": "upl-e5f6g7h8",
"fileName": "rubrica_aziendale.vcf",
"totalContacts": 342,
"parsedContacts": 339,
"errors": 3
}
Confirm the VCard import:
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/mapped/vcard \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"uploadId": "upl-e5f6g7h8",
"listId": 87
}'
{
"imported": 335,
"duplicates": 4,
"invalid": 3,
"listId": 87,
"totalInList": 5440
}
:::info Automatic VCard mapping Unlike CSV, VCard contacts use standard fields (FN, TEL, EMAIL, ADR) that are automatically mapped without requiring manual configuration. :::
Step 3 — Verify the contacts in the list
View the contacts present in the list with pagination.
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/list/87/contacts?page=0&size=10" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Contact listing
{
"content": [
{
"id": 24501,
"firstName": "Giulia",
"lastName": "Rossi",
"phoneNumber": "+393401234567",
"email": "giulia.rossi@example.it",
"valid": true
},
{
"id": 24502,
"firstName": "Marco",
"lastName": "Bianchi",
"phoneNumber": "+393489876543",
"email": "m.bianchi@example.it",
"valid": true
}
],
"totalElements": 5440,
"totalPages": 544,
"page": 0,
"size": 10
}
Step 4 — Use the list in a campaign
Pass the listId as contactListId in the campaign configuration:
curl -X PUT https://lora-api.agiletelecom.com/api/partner-gateway/v1/campaigns/1542 \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"sender": "ShopItalia",
"text": "Offerta esclusiva per i clienti del Nord Italia! -30% su tutto con codice NORD30.",
"contactListId": 87
}'
See UC-006 — Bulk SMS Campaign for the complete campaign sending flow.
Additional operations
Remove contacts from a list
curl -X DELETE https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts/list/contacts \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"contactIds": [24501],
"listIds": [87]
}'
{
"removed": 1
}
Search contacts by filter
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/contacts?city=Milano&page=0&size=20" \
-H "X-Api-Key: YOUR_API_KEY"
Quick endpoint reference
| Action | Method | Endpoint |
|---|---|---|
| List contacts | GET | /contacts |
| Create contact | POST | /contacts |
| Update contact | PUT | /contacts/{id} |
| Delete contacts | DELETE | /contacts |
| List of lists | GET | /contacts/list |
| Create list | POST | /contacts/list |
| Add to list | POST | /contacts/list/contacts |
| Remove from list | DELETE | /contacts/list/contacts |
| Contacts in list | GET | /contacts/list/{id}/contacts |
| Upload CSV | POST | /contacts/upload |
| Upload VCard | POST | /contacts/upload/vcard |
| Confirm CSV | POST | /contacts/mapped/file |
| Confirm VCard | POST | /contacts/mapped/vcard |
Common errors
| Problem | Probable cause | Solution |
|---|---|---|
HTTP 401 | Missing or invalid API Key | Check X-Api-Key header |
accepted: false | Insufficient credit or invalid number | Check credit; verify E.164 format |
HTTP 400 — Invalid CSV format | Malformed CSV or missing required columns | Verify the file has a header row and phone numbers in E.164 format |
HTTP 409 — Duplicate contact | Phone number already exists in the system | Use the existing contact ID or update instead of creating |
| VCard parse error | Unsupported VCard version or missing TEL field | Ensure VCard 3.0/4.0 format with valid phone numbers |
Expected result
| Step | Action | Result |
|---|---|---|
| 1 | POST /contacts/list | List created with id |
| 2a | POST /contacts + POST /contacts/list/contacts | Contact created and associated with list |
| 2b | POST /contacts/upload + POST /contacts/mapped/file | 5,104 contacts imported from CSV |
| 2c | POST /contacts/upload/vcard + POST /contacts/mapped/vcard | 335 contacts imported from VCard |
| 3 | GET /contacts/list/{id}/contacts | Paginated listing of contacts in the list |
| 4 | PUT /campaigns/{id} with contactListId | List associated with campaign |
Next steps
- UC-006 — Bulk SMS Campaign: Use the newly created lists to launch campaigns
- Contacts and Lists Guide: Deep dive into filters, pagination, and advanced management
- Export Guide: Export contacts for external analysis