Mono Colombia

Target discovery in sandbox

Test deterministic target discovery, alternatives, caching, and failures in the Bre-B sandbox

Use these deterministic scenarios to test target discovery without relying on real Bre-B directory data. They apply only at:

https://sandbox.api.cuentamono.com

Sandbox-only data

Use the sample identities and accounts only for testing. The suffix rules on this page are not available in production and do not describe real people or accounts.

Prerequisites and scopes

Use a sandbox tenant account and an access token with the scope required by each step. Ask Mono to enable target discovery for that sandbox tenant before testing:

StepScope
POST /api/v1/targets/discovertarget_discoveries
GET /api/v1/banks and GET /api/v1/banks/{ach_code}target_discoveries or target_discoveries:readonly
POST /api/v1/targets/resolve for the 102 alternativetarget_resolutions
POST /api/v1/outgoing_transfersoutgoing_transfers

See authentication and scopes for token setup.

Select a scenario with document_number

The last three characters of person.document_number are the only selector. Changing the email, phone, bank, or account does not select a different scenario.

SuffixResult
101Exact identification target after one prior same-person alternative
102No exact target; one identification alternative that can be resolved
103Empty result; a repeated identical request can demonstrate a negative cache hit
104Directory unavailable with HTTP 503
Any other suffixSame empty, cacheable result as 103

The document suffix is the only scenario selector. The requested bank and account remain valid inputs even when the account starts with 99; changing either one does not switch the sandbox scenario. However, the deterministic responses documented for 101 and 102 are guaranteed only when the requested account.number does not start with 99. That prefix is reserved for synthetic alternative destinations, which Mono derives independently.

102 is also reserved for direct resolution

A document-shaped plain key ending in 102 is reserved in sandbox for POST /api/v1/targets/resolve and for outgoing transfers paid by key. This lets the alternative returned by discovery resolve to the same deterministic destination.

Exact match: suffix 101

Send this request:

POST /api/v1/targets/discover
Content-Type: application/json
Authorization: Bearer <access_token>
{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "person": {
    "document_type": "CC",
    "document_number": "1192793101",
    "first_name": "Diego",
    "first_surname": "Sánchez",
    "phone": "+573104838791",
    "email": "diego@example.com"
  },
  "account": {
    "bank_code": "013",
    "number": "0013123456789",
    "type": "savings_account"
  }
}

The response is:

{
  "state": "discovered",
  "state_reason": null,
  "attempts_count": 2,
  "resolution_id": "bbtgr_5tgliBmzjZ6mpQPRbQjfKj",
  "target": {
    "id": "bbtgt_5tgliBmzjZ6mpQPRbQjfKj",
    "key_type": "identification",
    "key_value": "1192793101",
    "resolution_type": "plain_key",
    "spbvi": "CRB",
    "participant_nit": "860003020",
    "creditor": {
      "type": "natural",
      "document_type": "CC",
      "document_number": "1192793101",
      "full_name": "Diego Sánchez"
    },
    "creditor_account": {
      "type": "savings_account",
      "number": "0013123456789",
      "currency_code": "COP"
    },
    "transaction_amount": null,
    "payment_id": null
  },
  "same_person_keys": [
    {
      "key_type": "alphanumeric",
      "key_value": "@BBVA3104838791",
      "bank_code": "001",
      "participant_nit": "860002964",
      "creditor_account": {
        "type": "savings_account",
        "number_last_four": "2852",
        "currency_code": "COP"
      },
      "resolution_required": true
    }
  ]
}

For BBVA (bank_code=013), discovery tries the bank's alphanumeric template before the identification candidate. It observes the template as a same-person alternative, finds an exact match on the second attempt, and exits early. It does not try the later phone and email candidates.

attempts_count therefore depends on the selected bank's candidate order and templates; it is not the number of fields in the request. same_person_keys is non-exhaustive and contains only same-person candidates observed before the first exact match.

Only the winning exact target creates a resolution and emits target_resolution_created and target_resolution_resolved. The alternative does not emit resolution webhooks. Delivery is asynchronous, so target_resolution_created can already contain state=resolved.

Alternative only: suffix 102

Use the same payload with the document ending in 102:

POST /api/v1/targets/discover
Content-Type: application/json
Authorization: Bearer <access_token>
{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "person": {
    "document_type": "CC",
    "document_number": "1192793102",
    "first_name": "Diego",
    "first_surname": "Sánchez",
    "phone": "+573104838791",
    "email": "diego@example.com"
  },
  "account": {
    "bank_code": "013",
    "number": "0013123456789",
    "type": "savings_account"
  }
}

The full candidate walk returns:

{
  "state": "not_discovered",
  "state_reason": "no_exact_target",
  "attempts_count": 4,
  "resolution_id": null,
  "target": null,
  "same_person_keys": [
    {
      "key_type": "identification",
      "key_value": "1192793102",
      "bank_code": "007",
      "participant_nit": "890903938",
      "creditor_account": {
        "type": "savings_account",
        "number_last_four": "6809",
        "currency_code": "COP"
      },
      "resolution_required": true
    }
  ]
}

This result creates no target, resolution, or resolution webhook. Of the sandbox alternatives, only this identification alternative ending in 102 is guaranteed to support a later resolution.

Resolve and verify the 102 alternative

After the payer selects the alternative, resolve its exact key_value:

POST /api/v1/targets/resolve
Content-Type: application/json
Authorization: Bearer <access_token>
{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "format": "plain_key",
  "value": "1192793102"
}

The resolved response includes this deterministic destination:

{
  "id": "bbtgr_6tgliBmzjZ6mpQPRbQjfKj",
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "format": "plain_key",
  "value": "1192793102",
  "state": "resolved",
  "state_reason": null,
  "target": {
    "id": "bbtgt_6tgliBmzjZ6mpQPRbQjfKj",
    "key_type": "identification",
    "key_value": "1192793102",
    "resolution_type": "plain_key",
    "spbvi": "CRB",
    "participant_nit": "890903938",
    "creditor": {
      "type": "natural",
      "document_type": "CC",
      "document_number": "1192793102",
      "full_name": "Persona Sandbox"
    },
    "creditor_account": {
      "type": "savings_account",
      "number": "99023886809",
      "currency_code": "COP"
    },
    "transaction_amount": null,
    "payment_id": null
  }
}

The synthetic identity is always CC / Persona Sandbox, and the result is always an identification target for document-shaped values ending in 102. Before asking the payer to confirm, verify both of these invariants:

  1. The resolved target's participant_nit is 890903938, which corresponds to the alternative's ACH code 007.
  2. creditor_account.number ends in the advertised number_last_four value, 6809.

Do not pay the alternative if either the ACH destination or the last four digits changed.

Empty result and negative cache: suffix 103 or default

Use suffix 103 (or any suffix other than 101104) to get an empty result:

{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "person": {
    "document_type": "CC",
    "document_number": "1192793103",
    "first_name": "Diego",
    "first_surname": "Sánchez",
    "phone": "+573104838791",
    "email": "diego@example.com"
  },
  "account": {
    "bank_code": "013",
    "number": "0013123456789",
    "type": "savings_account"
  }
}

The first uncached response is:

{
  "state": "not_discovered",
  "state_reason": "no_exact_target",
  "attempts_count": 4,
  "resolution_id": null,
  "target": null,
  "same_person_keys": []
}

Repeat the identical request within one hour to exercise the negative cache:

{
  "state": "not_discovered",
  "state_reason": "no_exact_target",
  "attempts_count": 0,
  "resolution_id": null,
  "target": null,
  "same_person_keys": []
}

Only empty not_discovered results are cached, for up to one hour. A shared sandbox may already contain the same fingerprint, so the first request you observe can legitimately have attempts_count=0. If the sandbox does not have an HMAC available for discovery, negative results are not cached and each request performs the full candidate walk.

Unavailable directory: suffix 104

Send the normal payload with document 1192793104:

{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "person": {
    "document_type": "CC",
    "document_number": "1192793104",
    "first_name": "Diego",
    "first_surname": "Sánchez",
    "phone": "+573104838791",
    "email": "diego@example.com"
  },
  "account": {
    "bank_code": "013",
    "number": "0013123456789",
    "type": "savings_account"
  }
}

Discovery aborts on the first unavailable directory attempt and returns HTTP 503:

{
  "code": "503 Service Unavailable",
  "errors": [
    {
      "error_code": "service_is_unavailable",
      "message": "The service is unavailable, Please try again later",
      "path": null,
      "url": null
    }
  ],
  "id": "log_7MkWaFqvfosB8fzHhb1Eql",
  "message": "Service unavailable"
}

The error is not cached and creates no target, resolution, or webhook. Retry with bounded backoff, as you would for a transient production failure.

Use the resulting target in a transfer

The exact target from 101 and the newly resolved target from 102 are each single-use. Send the chosen target.id in one outgoing transfer:

{
  "tenant_account_id": "bbtacc_5tgliBmzjZ6mpQPRbQjfKj",
  "transfers": [
    {
      "external_id": "sandbox-discovery-001",
      "target_id": "bbtgt_6tgliBmzjZ6mpQPRbQjfKj",
      "amount": {
        "amount": 10000,
        "currency": "COP"
      }
    }
  ]
}

Alternatively, an outgoing transfer by plain_key with a document-shaped value ending in 102 resolves to the same deterministic destination. See outgoing transfers in sandbox and create outgoing transfers.

Bank catalog

GET /api/v1/banks and GET /api/v1/banks/{ach_code} use the normal sandbox catalog. They do not need a suffix or any other simulation value. Use their canonical ach_code values in discovery requests.

On this page