# Recovery using API

This section includes instructions and details relevant to performing a recovery in Unified feed using the API. Please make sure to read the provided description and information regarding the different endpoints and if available, notes on performing recovery in edge cases.

### Max recovery periods for producers <a href="#uofrecoveryusingapi-maxrecoveryperiodsforproducers" id="uofrecoveryusingapi-maxrecoveryperiodsforproducers"></a>

* **Custom Bet**: Unlimited
* **Gaming producers**: 3 hours
* **Live Odds producers**: 10 hours
* **Premium Cricket producer:** Instead of maximum recovery period, we ensure a minimum recovery period of 7 days. Maximum recovery period is 10 days or more in system (feed generator) which will not have any customer impact.
* **All other producers**: 72 hours

Refer to [Restrictions for Odds Recovery](https://docs.sportradar.com/uof/api-and-structure/api/odds-recovery/restrictions-for-odds-recovery).

### Recovery endpoints <a href="#uofrecoveryusingapi-recoveryendpoints" id="uofrecoveryusingapi-recoveryendpoints"></a>

| **HTTP** | **Endpoint**                                                                           | **Description**                                                                                                                                                                                                                                                                                         |
| -------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| POST     | `(product)/recovery/initiate_request?after=(timestamp)[&request_id=(x)][&node_id=(y)]` | All odds changes for sport events handled by this product. The timestamp must be no longer than the max recovery period per producer in the past.                                                                                                                                                       |
| POST     | `(product)/odds/events/(id)/initiate_request`                                          | All current odds for all the markets for one single match/race. The event must be either not\_started or live.                                                                                                                                                                                          |
| POST     | `(product)/stateful_messages/events/(id)/initiate_request`                             | <p>All stateful messages for the specified match/race. The event can be up to 30 days in the past.</p><p><em>Please note that the Premium Cricket producer supports only up to 7 days in the past.</em></p><p><em>and the hard limit for recovery for stateful messages in live odds is 7 days</em></p> |

All of these endpoints return either success or failure. If success, the actual messages come as one or more message per match over AMQP. The recovery sequence ends with a snapshot\_complete message being sent:&#x20;

```xml
<snapshot_complete request_id="1234" timestamp="1234578" product="3"/>
```

The (product) argument in the API (table above) can be one of the following: liveodds, pre, betpal, mts or virtuals

```
liveodds/recovery/initiate_request?after=(timestamp)[&request_id=(x)][&node_id=(y)]
```

All requests can have an additional parameter *request\_id=X*, Where X is an integer of your own choice. The contract is that if this request ID if present, it will be included in all stateful messages resulting from this call as an extra attribute, and it will be included in the snapshot\_complete message once all messages have been sent. You set a request\_id if you want to track the results of individual requests.

All requests can also have an additional (optional) parameter *node\_id=Y*, where Y is an integer of your choice. If you have multiple sessions, Betradar’s suggestion is that you use different numbers for different sessions. During the recovery the node\_id you passed in will be sent in as the 8<sup>th</sup> word in the routing key. This way you can add a binding key that ensures that you only receive recovery messages for your particular session, and not for your other sessions.

{% hint style="info" %}
**Note**: The SDKs automatically takes care of recovery.
{% endhint %}

The after parameter is specified in **milliseconds since Epoch UTC.** This is for example: <https://currentmillis.com/>

The after parameter should normally be set to the timestamp of the last message received. This should be the timestamp in the message itself, not something the client system computed when it read the message. If the timestamp is not too far in the past, the client system is guaranteed to have current odds for any active matches, and also all bet\_settlement, bet\_cancel and rollbacks that have happened inbetween the timestamp and now.

{% hint style="info" %}
**Note**: The client system receives current odds for active sport\_events. This does not necessarily mean all odds changes. If there have been multiple updates to a market, the client system will only receive the most recent one. If the complete odds change history is desired, this has to be requested for an individual match separately.
{% endhint %}

**This odds history is not available through the API, but can be downloaded through&#x20;*****Ctrl*****&#x20;or the&#x20;*****Live Booking Calendar*****&#x20;if needed.**

{% hint style="warning" %}
**Please be aware** that multiple [bet\_settlements](https://docs.sportradar.com/uof/data-and-features/messages/event/bet-settlement) can be merged into one single bet\_settlment message during recovery as well. For example: “*If a bet\_settlment was sent out at half-time for half-time markets, and another bet\_settlement was sent after the match, the recovery bet\_settlement for the same match will than include both the half-time and post-match markets in one message*”.
{% endhint %}

The client system may receive messages sent before the timestamp provided. The client system should be built robust enough to handle this.

The closer the after timestamp is to now, the better it is. If the last message you received was more than the max recovery period for the producer, this is too far in the past.

If the client system does not specify the after parameter, this means: “*I am new, just send me current active odds”*. The response to this is that all current odds for live matches (where odds are active) are sent. The Live Odds producer handles all the live matches, but the prematch [producers](https://docs.sportradar.com/uof/introduction/key-concepts/producers) sends all matches where we have generated odds, and the match\_status description=”not\_started”.

If the after parameter is too far in the past or in the future, it will result in the request getting rejected and if the client system was not subscribed previously, the client system will remain unsubscribed.

### Recovery and bet\_settlement messages <a href="#uofrecoveryusingapi-recoveryandbet_settlementmessages" id="uofrecoveryusingapi-recoveryandbet_settlementmessages"></a>

Please be aware that multiple bet\_settlements can be merged into one single bet\_settlement message during recovery as well. For example: “*If a bet\_settlement was sent out at half-time for half-time markets, and another bet\_settlement was sent after the match, the recovery bet\_settlement for the same match will than include **both** the half-time and post-match markets in one message*”.

### Recovering all bet settlements for a specific event <a href="#uofrecoveryusingapi-recoveringallbetsettlementsforaspecificevent" id="uofrecoveryusingapi-recoveringallbetsettlementsforaspecificevent"></a>

Under some circumstances you may have missed/lost some bet\_settlements in a match. Or you may want to recover the state of a match the results for a match that ended more than three days ago. In such cases, you can call a specific end-point to recover all bet\_settlements, bet\_cancels and rollbacks done for a particular event.

### Recovery sequence <a href="#uofrecoveryusingapi-recoverysequence" id="uofrecoveryusingapi-recoverysequence"></a>

Proper recovery requires the following steps:

* Before starting the recovery: Call the daily schedule for the next 3 days and cache the fixtures for all matches received. This will reduce the number of individual API calls later on
* Ensure you have an established AMQP session
* Call the recovery endpoint
* Until you receive a `snapshot_complete` for the previous recovery call, process like this:
  * Process `odds_changes` without a `recovery_id` as normal.\
    For `odds_change` messages *with* a `recovery_id`:
    * Process them as normal updates if you have no recent update for the specified sport event.
    * Ignore the message if you have already received a more recent update for that event. This selective ignoring ensures that only the *most current* information is applied during the recovery process."
  * If they are stateful messages (bet settlement, rollback bet settlement, bet cancel, rollback bet cancel) - store them in a queue for later processing
* When snapshot complete for the recovery request is received
  * Process all stateful messages in the queue received in the previous step
* After the snapshot complete: you can process all stateful messages directly without queueing them up
* As soon as you have received an odds\_change for a sport\_event even under the recovery, you open up the markets for that sport event. A conservative solution can wait until snapshot\_complete has been received and open up all markets for all received sport-events then, but this is not strictly necessary

{% hint style="info" %}
**Note**

After a possible disconnection, some market/line statuses may have changed, and these changes might not be fully reflected in regular `odds_changes` received *after* reconnecting. Therefore, it is critical to actively process `recovery_odds_changes` (applying the selective logic described above to prioritize the latest information) to ensure you have the most accurate and up-to-date status for every market you offer for an event.
{% endhint %}

Recovery sequence when an \<alive product="x" subscribed="0"/> is received

Whenever an alive message is received and the subscribed attribute in the message is set to 0, This means that a particular odds producer has been down (due to maintenance or some system error), and your system needs to initiate a partial recovery. This is done following the same steps as above, but in step two, only an API-call for the product that reported it was down is called. I.e. you receive:

```xml
<alive product="1" subscribed="0"/>
```

you call pre/recovery/initiate\_request and process messages as outlined above until *snapshot\_complete* is received.&#x20;

### Handling special states <a href="#uofrecoveryusingapi-handlingspecialstates" id="uofrecoveryusingapi-handlingspecialstates"></a>

{% hint style="info" %}
**Note**

The system has an *at-least-once-guarantee*. If something goes down, there is some risk that the same message is sent multiple times; your system should be built to handle this (for odds changes this is typically not a problem).
{% endhint %}

#### Forced betstop <a href="#uofrecoveryusingapi-forcedbetstop" id="uofrecoveryusingapi-forcedbetstop"></a>

In case of the following scenario:

* If the scheduled time for a match has started and the prematch odds producer provided the last odds.
* You have not received any odds from another producer, and no betstop from the prematch producer has been received.

In this case, the client system should automatically betstop all markets for the match. This is an extra precaution if the prematch system is down and you have not yet noticed this happening.

#### Handed\_over market state during recovery <a href="#uofrecoveryusingapi-handed_overmarketstateduringrecovery" id="uofrecoveryusingapi-handed_overmarketstateduringrecovery"></a>

During recovery a producer may send a message saying that some markets have been handed\_over. This is not a market state, but an indicator that since the disconnect happened this producer has handed over odds production for this market to another odds producer. If you already have received odds for this market from another odds producer, you can ignore this message, otherwise you should now mark this market as *suspended*. You should shortly receive odds from the other producer after it is handed over.&#x20;

#### Settled and cancelled market state during recovery <a href="#uofrecoveryusingapi-settledandcancelledmarketstateduringrecovery" id="uofrecoveryusingapi-settledandcancelledmarketstateduringrecovery"></a>

During recovery some markets can be sent with the market state *settled*. This means that [bet\_settlements](https://docs.sportradar.com/uof/data-and-features/messages/event/bet-settlement) already have been sent for this market. This can for example happen during the 2<sup>nd</sup> half in soccer, where the 1<sup>st</sup> half markets have already been *settled*. There is no more activity expected for this market (the only way the system can change this is to send a [rollback\_betsettlement](https://docs.sportradar.com/uof/data-and-features/messages/event/rollback-bet-settlements).

Similarly, during recovery a market can be sent with the market state *cancelled*, which should be treated in the same manner as above - no more activity is expected, and if you haven’t already received a [bet\_cancel](https://docs.sportradar.com/uof/data-and-features/messages/event/bet-cancel) when recovery ends, a bet\_cancel message has been missed somewhere.

#### General recommendations for market state handling when an Odds Producer is unavailable <a href="#uofrecoveryusingapi-generalrecommendationsformarketstatehandlingwhenanoddsproducerisunavailable" id="uofrecoveryusingapi-generalrecommendationsformarketstatehandlingwhenanoddsproducerisunavailable"></a>

If a match is live and the client system loses connection to the odds producer providing odds for that market, the client system must set all markets to *suspended* and stop accepting tickets.

If a match is not yet *live*, you have a choice: Either *suspend* all markets directly and stop accepting tickets. Alternatively, sport-events that are more than e.g. 2 hours from scheduled start time can be kept open as it is unlikely that there will be significant odds changes, and you are likely to get connected again shortly. **However**, we still recommend that if you haven’t been able to reconnect to the odds producer in \~10 minutes, stop all markets for all sport\_events for this odds producer as soon as possible.

### **Recovery Responses for Premium Cricket** <a href="#uofrecoveryusingapi-recoveryresponsesforpremiumcricket" id="uofrecoveryusingapi-recoveryresponsesforpremiumcricket"></a>

The following table depicts the recovery responses for premium cricket per match status

| **Recovery Type**                                                                                                                   | **Pre (Not started/About to start** | **Live**                                                                                          | **After/Ended**                                                                                   | **Min. Recovery Period** |
| ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------ |
| <p><strong>Full Odds Recovery</strong></p><p><strong>(</strong><em><strong>Without timestamp</strong></em><strong>)</strong></p>    | Only Odds Change                    | Only Odds Change                                                                                  | No recovery message once finished                                                                 | 7 days                   |
| <p><strong>Full Odds Recovery</strong></p><p><strong>(</strong><em><strong>With after timestamp</strong></em><strong>)</strong></p> | Only Odds Change                    | Both Odds Change and Bet Settlement                                                               | Both Odds Change and Bet Settlement                                                               | 3 days                   |
| **Sport Event Recovery**                                                                                                            | Only Odds Change                    | Only Odds Change                                                                                  | Only Odds Change                                                                                  | 7 days                   |
| **Stateful Recovery**                                                                                                               | No recovery response                | Only stateful messages (bet settlement, rollback bet settlement, bet cancel, rollback bet cancel) | Only stateful messages (bet settlement, rollback bet settlement, bet cancel, rollback bet cancel) | 7 days                   |

{% hint style="info" %}
Please note that

*\*\*No fixture change messages in recoveries for Premium Cricket*

*\*\*Finished matches can have following statuses:*

* *ENDED(3),*
* *CLOSED(4),*
* *CANCELLED(5),*
* *ABANDONED(9)*
  {% endhint %}
