# Ways to bring an audience in

Source: https://jointextkit.com/docs/api/contacts/import-sources
Index: https://jointextkit.com/llms.txt

`GET /v1/contacts/import/sources`

Where an audience can come from and every way to bring it here. Without `source`: the questions to ask (where the people are, which group, what you can sign in to, whether consent was recorded, once or synced) and the kinds of source we know. With `source` (free text, e.g. "Mixpanel" or "our Postgres users table"): the ways in, best first: an integration already syncing it, tools you already have for it, our 6-hourly sync, connected with your key here or in the console, a push to an ingest URL, a script against its API with a key from your environment, its export screen, and the console upload. Also lists the integrations already connected. Reads nothing else and changes nothing.

Send your API key as a bearer token: `Authorization: Bearer ssms_sk_...`. Test keys run this endpoint against the [sandbox](/docs/sandbox); see [Authentication](/docs/authentication) for key modes and scopes.

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `source` | string | No | Where the people are, in your words. Omit to get the questions first. |

## Responses

| Status | Meaning | Body |
| --- | --- | --- |
| 200 | The import plan | JSON object |
| 401 | Missing, malformed, or revoked API key | `Error` |
| 402 | Billable live calls only: the prepaid credit balance cannot cover the call (insufficient_credits); nothing was done or charged | `Error` |
| 429 | Rate limit or quota exceeded | `Error` |

### 200: response fields

| Field | Type | Description |
| --- | --- | --- |
| `object` | `import_plan` |  |
| `source` | object | Nullable. |
| `source.key` | string |  |
| `source.label` | string |  |
| `source.kind` | string |  |
| `source.synced` | boolean | We have our own sync for it |
| `source.consent` | string | Where it records SMS consent Nullable. |
| `questions` | array of string |  |
| `connected` | array of object |  |
| `connected[].id` | string |  |
| `connected[].provider` | string |  |
| `connected[].name` | string |  |
| `connected[].status` | string |  |
| `connected[].list_id` | string |  |
| `paths` | array of object |  |
| `paths[].method` | `connected`, `your_tools`, `integration`, `push`, `api`, `export`, `upload` |  |
| `paths[].title` | string |  |
| `paths[].when` | string |  |
| `paths[].steps` | array of string |  |
| `paths[].console_url` | string | The console page for this way in |
| `consent` | string | How consent carries over |

## Errors

| Status | When |
| --- | --- |
| 401 | Missing, malformed, or revoked API key |
| 402 | Billable live calls only: the prepaid credit balance cannot cover the call (insufficient_credits); nothing was done or charged |
| 429 | Rate limit or quota exceeded |

Every error has the same JSON shape, and `request_id` matches the `X-Request-Id` response header. [Errors](/docs/errors) lists every code and what to do about it.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "What went wrong, in plain words.",
    "param": "the_field",
    "request_id": "req_a1B2c3D4e5F6g7H8"
  }
}
```

## Examples

### Node.js

The Node.js SDK does not wrap this endpoint yet; call it over HTTP.

```javascript
const res = await fetch('https://api.jointextkit.com/v1/contacts/import/sources', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.TEXTKIT_API_KEY}`,
  },
});

if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();
```

### PHP

```php
<?php

$ch = curl_init('https://api.jointextkit.com/v1/contacts/import/sources');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('TEXTKIT_API_KEY'),
    ],
]);

$data = json_decode(curl_exec($ch), true);
```

### Python

The Python SDK does not wrap this endpoint yet; call it over HTTP.

```python
import json, os, urllib.request

req = urllib.request.Request(
    "https://api.jointextkit.com/v1/contacts/import/sources",
    method="GET",
    headers={
        "Authorization": f"Bearer {os.environ['TEXTKIT_API_KEY']}",
    },
)
with urllib.request.urlopen(req) as res:
    data = json.load(res)
```

### Ruby

```ruby
require "net/http"
require "json"

uri = URI("https://api.jointextkit.com/v1/contacts/import/sources")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV["TEXTKIT_API_KEY"]}"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
```

### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.jointextkit.com/v1/contacts/import/sources", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("TEXTKIT_API_KEY"))

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	data, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(data))
}
```

### Rust

```rust
// cargo add reqwest --features blocking,json
// cargo add serde_json

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("TEXTKIT_API_KEY")?;
    let res = reqwest::blocking::Client::new()
        .get("https://api.jointextkit.com/v1/contacts/import/sources")
        .bearer_auth(key)
        .send()?
        .error_for_status()?;
    let data: serde_json::Value = res.json()?;
    println!("{data}");
    Ok(())
}
```

### Java

```java
import java.net.URI;
import java.net.http.*;

public class Main {
    public static void main(String[] args) throws Exception {
        var request = HttpRequest.newBuilder(URI.create("https://api.jointextkit.com/v1/contacts/import/sources"))
            .header("Authorization", "Bearer " + System.getenv("TEXTKIT_API_KEY"))
            .GET()
            .build();

        var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}
```

### .NET

```csharp
using System.Net.Http.Headers;

var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("TEXTKIT_API_KEY"));

var res = await http.GetAsync("https://api.jointextkit.com/v1/contacts/import/sources");
res.EnsureSuccessStatusCode();

var data = await res.Content.ReadAsStringAsync();
```

### cURL

```bash
curl -X GET "https://api.jointextkit.com/v1/contacts/import/sources" \
  -H "Authorization: Bearer $TEXTKIT_API_KEY"
```

## Related

- Guide: [Contacts](/docs/contacts)
- [All contacts endpoints](/docs/api#contacts)
- [API reference](/docs/api)
